<commit_before>#![allow(missing_docs, nonstandard_style)]

use crate::ffi::{OsStr, OsString};
use crate::io::ErrorKind;
use crate::os::windows::ffi::{OsStrExt, OsStringExt};
use crate::path::PathBuf;
use crate::time::Duration;

pub use self::rand::hashmap_random_keys;
pub use libc::strlen;

#[macro_use]
pub mod compat;

pub mod alloc;
pub mod args;
pub mod c;
pub mod cmath;
pub mod condvar;
pub mod env;
pub mod fs;
pub mod handle;
pub mod io;
pub mod memchr;
pub mod mutex;
pub mod net;
pub mod os;
pub mod os_str;
pub mod path;
pub mod pipe;
pub mod process;
pub mod rand;
pub mod rwlock;
pub mod thread;
pub mod thread_local_dtor;
pub mod thread_local_key;
pub mod thread_parker;
pub mod time;
cfg_if::cfg_if! {
    if #[cfg(not(target_vendor = "uwp"))] {
        pub mod stdio;
        pub mod stack_overflow;
    } else {
        pub mod stdio_uwp;
        pub mod stack_overflow_uwp;
        pub use self::stdio_uwp as stdio;
        pub use self::stack_overflow_uwp as stack_overflow;
    }
}

// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
    stack_overflow::init();
}

// SAFETY: must be called only once during runtime cleanup.
// NOTE: this is not guaranteed to run, for example when the program aborts.
pub unsafe fn cleanup() {
    net::cleanup();
}

pub fn decode_error_kind(errno: i32) -> ErrorKind {
    match errno as c::DWORD {
        c::ERROR_ACCESS_DENIED => return ErrorKind::PermissionDenied,
        c::ERROR_ALREADY_EXISTS => return ErrorKind::AlreadyExists,
        c::ERROR_FILE_EXISTS => return ErrorKind::AlreadyExists,
        c::ERROR_BROKEN_PIPE => return ErrorKind::BrokenPipe,
        c::ERROR_FILE_NOT_FOUND => return ErrorKind::NotFound,
        c::ERROR_PATH_NOT_FOUND => return ErrorKind::NotFound,
        c::ERROR_NO_DATA => return ErrorKind::BrokenPipe,
        c::ERROR_INVALID_PARAMETER => return ErrorKind::InvalidInput,
        c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return ErrorKind::OutOfMemory,
        c::ERROR_SEM_TIMEOUT
        | c::WAIT_TIMEOUT
        | c::ERROR_DRIVER_CANCEL_TIMEOUT
        | c::ERROR_OPERATION_ABORTED
        | c::ERROR_SERVICE_REQUEST_TIMEOUT
        | c::ERROR_COUNTER_TIMEOUT
        | c::ERROR_TIMEOUT
        | c::ERROR_RESOURCE_CALL_TIMED_OUT
        | c::ERROR_CTX_MODEM_RESPONSE_TIMEOUT
        | c::ERROR_CTX_CLIENT_QUERY_TIMEOUT
        | c::FRS_ERR_SYSVOL_POPULATE_TIMEOUT
        | c::ERROR_DS_TIMELIMIT_EXCEEDED
        | c::DNS_ERROR_RECORD_TIMED_OUT
        | c::ERROR_IPSEC_IKE_TIMED_OUT
        | c::ERROR_RUNLEVEL_SWITCH_TIMEOUT
        | c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return ErrorKind::TimedOut,
        c::ERROR_CALL_NOT_IMPLEMENTED => return ErrorKind::Unsupported,
        _ => {}
    }

    match errno {
        c::WSAEACCES => ErrorKind::PermissionDenied,
        c::WSAEADDRINUSE => ErrorKind::AddrInUse,
        c::WSAEADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
        c::WSAECONNABORTED => ErrorKind::ConnectionAborted,
        c::WSAECONNREFUSED => ErrorKind::ConnectionRefused,
        c::WSAECONNRESET => ErrorKind::ConnectionReset,
        c::WSAEINVAL => ErrorKind::InvalidInput,
        c::WSAENOTCONN => ErrorKind::NotConnected,
        c::WSAEWOULDBLOCK => ErrorKind::WouldBlock,
        c::WSAETIMEDOUT => ErrorKind::TimedOut,

        _ => ErrorKind::Uncategorized,
    }
}

pub fn unrolled_find_u16s(needle: u16, haystack: &[u16]) -> Option<usize> {
    let ptr = haystack.as_ptr();
    let mut start = &haystack[..];

    // For performance reasons unfold the loop eight times.
    while start.len() >= 8 {
        macro_rules! if_return {
            ($($n:literal,)+) => {
                $(
                    if start[$n] == needle {
                        return Some((&start[$n] as *const u16 as usize - ptr as usize) / 2);
                    }
                )+
            }
        }

        if_return!(0, 1, 2, 3, 4, 5, 6, 7,);

        start = &start[8..];
    }

    for c in start {
        if *c == needle {
            return Some((c as *const u16 as usize - ptr as usize) / 2);
        }
    }
    None
}

pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> crate::io::Result<Vec<u16>> {
    fn inner(s: &OsStr) -> crate::io::Result<Vec<u16>> {
        let mut maybe_result: Vec<u16> = s.encode_wide().collect();
        if unrolled_find_u16s(0, &maybe_result).is_some() {
            return Err(crate::io::Error::new_const(
                ErrorKind::InvalidInput,
                &"strings passed to WinAPI cannot contain NULs",
            ));
        }
        maybe_result.push(0);
        Ok(maybe_result)
    }
    inner(s.as_ref())
}

// Many Windows APIs follow a pattern of where we hand a buffer and then they
// will report back to us how large the buffer should be or how many bytes
// currently reside in the buffer. This function is an abstraction over these
// functions by making them easier to call.
//
// The first callback, `f1`, is yielded a (pointer, len) pair which can be
// passed to a syscall. The `ptr` is valid for `len` items (u16 in this case).
// The closure is expected to return what the syscall returns which will be
// interpreted by this function to determine if the syscall needs to be invoked
// again (with more buffer space).
//
// Once the syscall has completed (errors bail out early) the second closure is
// yielded the data which has been read from the syscall. The return value
// from this closure is then the return value of the function.
fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> crate::io::Result<T>
where
    F1: FnMut(*mut u16, c::DWORD) -> c::DWORD,
    F2: FnOnce(&[u16]) -> T,
{
    // Start off with a stack buf but then spill over to the heap if we end up
    // needing more space.
    let mut stack_buf = [0u16; 512];
    let mut heap_buf = Vec::new();
    unsafe {
        let mut n = stack_buf.len();
        loop {
            let buf = if n <= stack_buf.len() {
                &mut stack_buf[..]
            } else {
                let extra = n - heap_buf.len();
                heap_buf.reserve(extra);
                heap_buf.set_len(n);
                &mut heap_buf[..]
            };

            // This function is typically called on windows API functions which
            // will return the correct length of the string, but these functions
            // also return the `0` on error. In some cases, however, the
            // returned "correct length" may actually be 0!
            //
            // To handle this case we call `SetLastError` to reset it to 0 and
            // then check it again if we get the "0 error value". If the "last
            // error" is still 0 then we interpret it as a 0 length buffer and
            // not an actual error.
            c::SetLastError(0);
            let k = match f1(buf.as_mut_ptr(), n as c::DWORD) {
                0 if c::GetLastError() == 0 => 0,
                0 => return Err(crate::io::Error::last_os_error()),
                n => n,
            } as usize;
            if k == n && c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER {
                n *= 2;
            } else if k >= n {
                n = k;
            } else {
                return Ok(f2(&buf[..k]));
            }
        }
    }
}

fn os2path(s: &[u16]) -> PathBuf {
    PathBuf::from(OsString::from_wide(s))
}

pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] {
    match unrolled_find_u16s(0, v) {
        // don't include the 0
        Some(i) => &v[..i],
        None => v,
    }
}

pub trait IsZero {
    fn is_zero(&self) -> bool;
}

macro_rules! impl_is_zero {
    ($($t:ident)*) => ($(impl IsZero for $t {
        fn is_zero(&self) -> bool {
            *self == 0
        }
    })*)
}

impl_is_zero! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }

pub fn cvt<I: IsZero>(i: I) -> crate::io::Result<I> {
    if i.is_zero() { Err(crate::io::Error::last_os_error()) } else { Ok(i) }
}

pub fn dur2timeout(dur: Duration) -> c::DWORD {
    // Note that a duration is a (u64, u32) (seconds, nanoseconds) pair, and the
    // timeouts in windows APIs are typically u32 milliseconds. To translate, we
    // have two pieces to take care of:
    //
    // * Nanosecond precision is rounded up
    // * Greater than u32::MAX milliseconds (50 days) is rounded up to INFINITE
    //   (never time out).
    dur.as_secs()
        .checked_mul(1000)
        .and_then(|ms| ms.checked_add((dur.subsec_nanos() as u64) / 1_000_000))
        .and_then(|ms| ms.checked_add(if dur.subsec_nanos() % 1_000_000 > 0 { 1 } else { 0 }))
        .map(|ms| if ms > <c::DWORD>::MAX as u64 { c::INFINITE } else { ms as c::DWORD })
        .unwrap_or(c::INFINITE)
}

/// Use `__fastfail` to abort the process
///
/// This is the same implementation as in libpanic_abort's `__rust_start_panic`. See
/// that function for more information on `__fastfail`
#[allow(unreachable_code)]
pub fn abort_internal() -> ! {
    const FAST_FAIL_FATAL_APP_EXIT: usize = 7;
    unsafe {
        cfg_if::cfg_if! {
            if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
                asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT);
                crate::intrinsics::unreachable();
            } else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] {
                asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT);
                crate::intrinsics::unreachable();
            } else if #[cfg(target_arch = "aarch64")] {
                asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT);
                crate::intrinsics::unreachable();
            }
        }
    }
    crate::intrinsics::abort();
}
<commit_msg>ErrorKind: Reformat the mapping table (windows)<commit_after>#![allow(missing_docs, nonstandard_style)]

use crate::ffi::{OsStr, OsString};
use crate::io::ErrorKind;
use crate::os::windows::ffi::{OsStrExt, OsStringExt};
use crate::path::PathBuf;
use crate::time::Duration;

pub use self::rand::hashmap_random_keys;
pub use libc::strlen;

#[macro_use]
pub mod compat;

pub mod alloc;
pub mod args;
pub mod c;
pub mod cmath;
pub mod condvar;
pub mod env;
pub mod fs;
pub mod handle;
pub mod io;
pub mod memchr;
pub mod mutex;
pub mod net;
pub mod os;
pub mod os_str;
pub mod path;
pub mod pipe;
pub mod process;
pub mod rand;
pub mod rwlock;
pub mod thread;
pub mod thread_local_dtor;
pub mod thread_local_key;
pub mod thread_parker;
pub mod time;
cfg_if::cfg_if! {
    if #[cfg(not(target_vendor = "uwp"))] {
        pub mod stdio;
        pub mod stack_overflow;
    } else {
        pub mod stdio_uwp;
        pub mod stack_overflow_uwp;
        pub use self::stdio_uwp as stdio;
        pub use self::stack_overflow_uwp as stack_overflow;
    }
}

// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
    stack_overflow::init();
}

// SAFETY: must be called only once during runtime cleanup.
// NOTE: this is not guaranteed to run, for example when the program aborts.
pub unsafe fn cleanup() {
    net::cleanup();
}

pub fn decode_error_kind(errno: i32) -> ErrorKind {
    use ErrorKind::*;

    match errno as c::DWORD {
        c::ERROR_ACCESS_DENIED => return PermissionDenied,
        c::ERROR_ALREADY_EXISTS => return AlreadyExists,
        c::ERROR_FILE_EXISTS => return AlreadyExists,
        c::ERROR_BROKEN_PIPE => return BrokenPipe,
        c::ERROR_FILE_NOT_FOUND => return NotFound,
        c::ERROR_PATH_NOT_FOUND => return NotFound,
        c::ERROR_NO_DATA => return BrokenPipe,
        c::ERROR_INVALID_PARAMETER => return InvalidInput,
        c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory,
        c::ERROR_SEM_TIMEOUT
        | c::WAIT_TIMEOUT
        | c::ERROR_DRIVER_CANCEL_TIMEOUT
        | c::ERROR_OPERATION_ABORTED
        | c::ERROR_SERVICE_REQUEST_TIMEOUT
        | c::ERROR_COUNTER_TIMEOUT
        | c::ERROR_TIMEOUT
        | c::ERROR_RESOURCE_CALL_TIMED_OUT
        | c::ERROR_CTX_MODEM_RESPONSE_TIMEOUT
        | c::ERROR_CTX_CLIENT_QUERY_TIMEOUT
        | c::FRS_ERR_SYSVOL_POPULATE_TIMEOUT
        | c::ERROR_DS_TIMELIMIT_EXCEEDED
        | c::DNS_ERROR_RECORD_TIMED_OUT
        | c::ERROR_IPSEC_IKE_TIMED_OUT
        | c::ERROR_RUNLEVEL_SWITCH_TIMEOUT
        | c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return TimedOut,
        c::ERROR_CALL_NOT_IMPLEMENTED => return Unsupported,
        _ => {}
    }

    match errno {
        c::WSAEACCES => PermissionDenied,
        c::WSAEADDRINUSE => AddrInUse,
        c::WSAEADDRNOTAVAIL => AddrNotAvailable,
        c::WSAECONNABORTED => ConnectionAborted,
        c::WSAECONNREFUSED => ConnectionRefused,
        c::WSAECONNRESET => ConnectionReset,
        c::WSAEINVAL => InvalidInput,
        c::WSAENOTCONN => NotConnected,
        c::WSAEWOULDBLOCK => WouldBlock,
        c::WSAETIMEDOUT => TimedOut,

        _ => Uncategorized,
    }
}

pub fn unrolled_find_u16s(needle: u16, haystack: &[u16]) -> Option<usize> {
    let ptr = haystack.as_ptr();
    let mut start = &haystack[..];

    // For performance reasons unfold the loop eight times.
    while start.len() >= 8 {
        macro_rules! if_return {
            ($($n:literal,)+) => {
                $(
                    if start[$n] == needle {
                        return Some((&start[$n] as *const u16 as usize - ptr as usize) / 2);
                    }
                )+
            }
        }

        if_return!(0, 1, 2, 3, 4, 5, 6, 7,);

        start = &start[8..];
    }

    for c in start {
        if *c == needle {
            return Some((c as *const u16 as usize - ptr as usize) / 2);
        }
    }
    None
}

pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> crate::io::Result<Vec<u16>> {
    fn inner(s: &OsStr) -> crate::io::Result<Vec<u16>> {
        let mut maybe_result: Vec<u16> = s.encode_wide().collect();
        if unrolled_find_u16s(0, &maybe_result).is_some() {
            return Err(crate::io::Error::new_const(
                ErrorKind::InvalidInput,
                &"strings passed to WinAPI cannot contain NULs",
            ));
        }
        maybe_result.push(0);
        Ok(maybe_result)
    }
    inner(s.as_ref())
}

// Many Windows APIs follow a pattern of where we hand a buffer and then they
// will report back to us how large the buffer should be or how many bytes
// currently reside in the buffer. This function is an abstraction over these
// functions by making them easier to call.
//
// The first callback, `f1`, is yielded a (pointer, len) pair which can be
// passed to a syscall. The `ptr` is valid for `len` items (u16 in this case).
// The closure is expected to return what the syscall returns which will be
// interpreted by this function to determine if the syscall needs to be invoked
// again (with more buffer space).
//
// Once the syscall has completed (errors bail out early) the second closure is
// yielded the data which has been read from the syscall. The return value
// from this closure is then the return value of the function.
fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> crate::io::Result<T>
where
    F1: FnMut(*mut u16, c::DWORD) -> c::DWORD,
    F2: FnOnce(&[u16]) -> T,
{
    // Start off with a stack buf but then spill over to the heap if we end up
    // needing more space.
    let mut stack_buf = [0u16; 512];
    let mut heap_buf = Vec::new();
    unsafe {
        let mut n = stack_buf.len();
        loop {
            let buf = if n <= stack_buf.len() {
                &mut stack_buf[..]
            } else {
                let extra = n - heap_buf.len();
                heap_buf.reserve(extra);
                heap_buf.set_len(n);
                &mut heap_buf[..]
            };

            // This function is typically called on windows API functions which
            // will return the correct length of the string, but these functions
            // also return the `0` on error. In some cases, however, the
            // returned "correct length" may actually be 0!
            //
            // To handle this case we call `SetLastError` to reset it to 0 and
            // then check it again if we get the "0 error value". If the "last
            // error" is still 0 then we interpret it as a 0 length buffer and
            // not an actual error.
            c::SetLastError(0);
            let k = match f1(buf.as_mut_ptr(), n as c::DWORD) {
                0 if c::GetLastError() == 0 => 0,
                0 => return Err(crate::io::Error::last_os_error()),
                n => n,
            } as usize;
            if k == n && c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER {
                n *= 2;
            } else if k >= n {
                n = k;
            } else {
                return Ok(f2(&buf[..k]));
            }
        }
    }
}

fn os2path(s: &[u16]) -> PathBuf {
    PathBuf::from(OsString::from_wide(s))
}

pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] {
    match unrolled_find_u16s(0, v) {
        // don't include the 0
        Some(i) => &v[..i],
        None => v,
    }
}

pub trait IsZero {
    fn is_zero(&self) -> bool;
}

macro_rules! impl_is_zero {
    ($($t:ident)*) => ($(impl IsZero for $t {
        fn is_zero(&self) -> bool {
            *self == 0
        }
    })*)
}

impl_is_zero! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }

pub fn cvt<I: IsZero>(i: I) -> crate::io::Result<I> {
    if i.is_zero() { Err(crate::io::Error::last_os_error()) } else { Ok(i) }
}

pub fn dur2timeout(dur: Duration) -> c::DWORD {
    // Note that a duration is a (u64, u32) (seconds, nanoseconds) pair, and the
    // timeouts in windows APIs are typically u32 milliseconds. To translate, we
    // have two pieces to take care of:
    //
    // * Nanosecond precision is rounded up
    // * Greater than u32::MAX milliseconds (50 days) is rounded up to INFINITE
    //   (never time out).
    dur.as_secs()
        .checked_mul(1000)
        .and_then(|ms| ms.checked_add((dur.subsec_nanos() as u64) / 1_000_000))
        .and_then(|ms| ms.checked_add(if dur.subsec_nanos() % 1_000_000 > 0 { 1 } else { 0 }))
        .map(|ms| if ms > <c::DWORD>::MAX as u64 { c::INFINITE } else { ms as c::DWORD })
        .unwrap_or(c::INFINITE)
}

/// Use `__fastfail` to abort the process
///
/// This is the same implementation as in libpanic_abort's `__rust_start_panic`. See
/// that function for more information on `__fastfail`
#[allow(unreachable_code)]
pub fn abort_internal() -> ! {
    const FAST_FAIL_FATAL_APP_EXIT: usize = 7;
    unsafe {
        cfg_if::cfg_if! {
            if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
                asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT);
                crate::intrinsics::unreachable();
            } else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] {
                asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT);
                crate::intrinsics::unreachable();
            } else if #[cfg(target_arch = "aarch64")] {
                asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT);
                crate::intrinsics::unreachable();
            }
        }
    }
    crate::intrinsics::abort();
}
<|endoftext|>


<commit_before>#[macro_use]
mod common;

use common::util::*;

static UTIL_NAME: &'static str = "basename";

fn expect_successful_stdout(input: Vec<&str>, expected: &str) {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let results = ucmd.args(&input).run();
    assert_empty_stderr!(results);
    assert!(results.success);
    assert_eq!(expected, results.stdout.trim_right());
}

#[test]
fn test_directory() {
    let dir = "/root/alpha/beta/gamma/delta/epsilon/omega/";
    expect_successful_stdout(vec![dir], "omega");
}

#[test]
fn test_file() {
    let file = "/etc/passwd";
    expect_successful_stdout(vec![file], "passwd");
}

#[test]
fn test_remove_suffix() {
    let path = "/usr/local/bin/reallylongexecutable.exe";
    expect_successful_stdout(vec![path, ".exe"], "reallylongexecutable");
}

#[test]
fn test_dont_remove_suffix() {
    let path = "/foo/bar/baz";
    expect_successful_stdout(vec![path, "baz"], "baz");
}

fn expect_error(input: Vec<&str>, expected_stdout: &str) {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let results = ucmd.args(&input).run();
    assert!(!results.success);
    assert!(results.stderr.len() > 0);
    assert_eq!(expected_stdout, results.stdout.trim_right());
}
#[cfg_attr(not(feature="test_unimplemented"),ignore)]
#[test]
fn test_multiple_param() {
    for multiple_param in vec!["-a", "--multiple"] {
        let path = "/foo/bar/baz";
        expect_successful_stdout(vec![multiple_param, path, path], "baz\nbaz");
    }
}

#[cfg_attr(not(feature="test_unimplemented"),ignore)]
#[test]
fn test_suffix_param() {
    for suffix_param in vec!["-s", "--suffix"] {
        let path = "/foo/bar/baz.exe";
        let suffix = ".exe";
        expect_successful_stdout(
            vec![suffix_param, suffix, path, path],
            "baz\nbaz"
        );
    }
}

#[cfg_attr(not(feature="test_unimplemented"),ignore)]
#[test]
fn test_zero_param() {
    for zero_param in vec!["-z", "--zero"] {
        let path = "/foo/bar/baz";
        expect_successful_stdout(vec![zero_param, "-a", path, path], "baz\0baz\0");
    }
}
<commit_msg>basename: tests for bad inputs<commit_after>#[macro_use]
mod common;

use common::util::*;

static UTIL_NAME: &'static str = "basename";

fn expect_successful_stdout(input: Vec<&str>, expected: &str) {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let results = ucmd.args(&input).run();
    assert_empty_stderr!(results);
    assert!(results.success);
    assert_eq!(expected, results.stdout.trim_right());
}

#[test]
fn test_directory() {
    let dir = "/root/alpha/beta/gamma/delta/epsilon/omega/";
    expect_successful_stdout(vec![dir], "omega");
}

#[test]
fn test_file() {
    let file = "/etc/passwd";
    expect_successful_stdout(vec![file], "passwd");
}

#[test]
fn test_remove_suffix() {
    let path = "/usr/local/bin/reallylongexecutable.exe";
    expect_successful_stdout(vec![path, ".exe"], "reallylongexecutable");
}

#[test]
fn test_dont_remove_suffix() {
    let path = "/foo/bar/baz";
    expect_successful_stdout(vec![path, "baz"], "baz");
}

fn expect_error(input: Vec<&str>, expected_stdout: &str) {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let results = ucmd.args(&input).run();
    assert!(!results.success);
    assert!(results.stderr.len() > 0);
    assert_eq!(expected_stdout, results.stdout.trim_right());
}
#[cfg_attr(not(feature="test_unimplemented"),ignore)]
#[test]
fn test_multiple_param() {
    for multiple_param in vec!["-a", "--multiple"] {
        let path = "/foo/bar/baz";
        expect_successful_stdout(vec![multiple_param, path, path], "baz\nbaz");
    }
}

#[cfg_attr(not(feature="test_unimplemented"),ignore)]
#[test]
fn test_suffix_param() {
    for suffix_param in vec!["-s", "--suffix"] {
        let path = "/foo/bar/baz.exe";
        let suffix = ".exe";
        expect_successful_stdout(
            vec![suffix_param, suffix, path, path],
            "baz\nbaz"
        );
    }
}

#[cfg_attr(not(feature="test_unimplemented"),ignore)]
#[test]
fn test_zero_param() {
    for zero_param in vec!["-z", "--zero"] {
        let path = "/foo/bar/baz";
        expect_successful_stdout(vec![zero_param, "-a", path, path], "baz\0baz\0");
    }
}

#[test]
fn test_invalid_option() {
    let path = "/foo/bar/baz";
    expect_error(vec!["-q", path], "");
}

#[test]
fn test_no_args() {
    expect_error(vec![], "");
}

#[test]
fn test_too_many_args() {
    expect_error(vec!["a", "b", "c"], "");
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod coinnect_tests {
    extern crate coinnect;

    use self::coinnect::coinnect::Coinnect;
    use self::coinnect::exchange::{ Exchange, ExchangeApi };
    use self::coinnect::pair::Pair;

    #[test]
    fn can_create_new_api_connection_to_bitstamp() {
        let api: Box<ExchangeApi> = Coinnect::new(Exchange::Bitstamp, "bs_api_key", "bs_api_secret", Some("bs_cust_id"));

        assert_eq!(format!("{:?}", api), "BitstampApi { \
                                                last_request: 0, \
                                                api_key: \"bs_api_key\", \
                                                api_secret: \"bs_api_secret\", \
                                                customer_id: \"bs_cust_id\", \
                                                http_client: Client { \
                                                    redirect_policy: FollowAll, \
                                                    read_timeout: None, \
                                                    write_timeout: None, \
                                                    proxy: None \
                                                } \
                                            }");
    }
    #[test]
    fn can_create_new_api_connection_to_kraken() {
//        let api = Coinnect::new(Exchange::Kraken, "", "", "");
//        assert_eq!(api, Exchange::Kraken);
    }
    #[test]
    fn can_create_new_api_connection_to_poloniex() {
//        let api = Coinnect::new(Exchange::Poloniex, "", "", "");
//        assert_eq!(api, Exchange::Poloniex);
    }

    #[test]
    fn coinnect_can_get_a_ticker_from_bitstamp() {
        let mut api = Coinnect::new(Exchange::Bitstamp, "bs_api_key", "bs_api_secret", Some("bs_cust_id"));
        let ticker = api.ticker(Pair::BTC_USD);

        assert!( ticker.unwrap().timestamp != 0 );
    }

    #[test]
    fn coinnect_should_return_an_order_book_from_bitstamp() {
        let mut api = Coinnect::new(Exchange::Bitstamp, "bs_api_key", "bs_api_secret", Some("bs_cust_id"));
        let order_book = api.return_order_book(Pair::BTC_USD);
        assert!( order_book.is_some() );
    }
    #[test]
    fn order_book_should_have_bids() {
        let mut api = Coinnect::new(Exchange::Bitstamp, "bs_api_key", "bs_api_secret", Some("bs_cust_id"));
        let result = api.return_order_book(Pair::BTC_USD);
        assert!( result.unwrap().contains_key("bids") );
    }

    #[test]
    fn should_return_the_trade_history_for_btc_usd_from_bitstamp() {
        let mut api = Coinnect::new(Exchange::Bitstamp, "bs_api_key", "bs_api_secret", Some("bs_cust_id"));
        let result = api.return_trade_history(Pair::BTC_USD);

        assert_eq!( result.is_some(), false );
    }

    // IMPORTANT: Real keys are needed in order to retrieve the balance
    #[test]
    fn balance_should_have_usd_btc_fee() {
        use std::path::PathBuf;
        let path = PathBuf::from("./keys_real.json");
        let mut api = Coinnect::new_from_file(Exchange::Bitstamp, "account_bitstamp", path);
        let result = api.return_balances(Pair::BTC_USD).unwrap();
        let result_looking_for_usd = result.clone();
        let result_looking_for_btc = result.clone();
        let result_looking_for_fee = result.clone();

        assert!(result_looking_for_usd.contains_key("usd_balance"));
        assert!(result_looking_for_btc.contains_key("btc_balance"));
        assert!(result_looking_for_fee.contains_key("fee"));
    }
}
<commit_msg>Delete tests related to non-yet established types (orderbook, history). Fix cfg_attr.<commit_after>#[cfg(test)]
mod coinnect_tests {
    extern crate coinnect;

    use self::coinnect::coinnect::Coinnect;
    use self::coinnect::exchange::{ Exchange, ExchangeApi };
    use self::coinnect::pair::Pair;

    #[test]
    fn can_create_new_api_connection_to_bitstamp() {
        let api: Box<ExchangeApi> = Coinnect::new(Exchange::Bitstamp, "bs_api_key", "bs_api_secret", Some("bs_cust_id"));

        assert_eq!(format!("{:?}", api), "BitstampApi { \
                                                last_request: 0, \
                                                api_key: \"bs_api_key\", \
                                                api_secret: \"bs_api_secret\", \
                                                customer_id: \"bs_cust_id\", \
                                                http_client: Client { \
                                                    redirect_policy: FollowAll, \
                                                    read_timeout: None, \
                                                    write_timeout: None, \
                                                    proxy: None \
                                                } \
                                            }");
    }
    #[test]
    fn can_create_new_api_connection_to_kraken() {
//        let api = Coinnect::new(Exchange::Kraken, "", "", "");
//        assert_eq!(api, Exchange::Kraken);
    }
    #[test]
    fn can_create_new_api_connection_to_poloniex() {
//        let api = Coinnect::new(Exchange::Poloniex, "", "", "");
//        assert_eq!(api, Exchange::Poloniex);
    }

    #[test]
    fn coinnect_can_get_a_ticker_from_bitstamp() {
        let mut api = Coinnect::new(Exchange::Bitstamp, "bs_api_key", "bs_api_secret", Some("bs_cust_id"));
        let ticker = api.ticker(Pair::BTC_USD);

        assert!( ticker.unwrap().timestamp != 0 );
    }

    // IMPORTANT: Real keys are needed in order to retrieve the balance
    #[test]
    #[cfg_attr(not(feature = "bitstamp_private_tests"), ignore)]
    fn balance_should_have_usd_btc_fee() {
        use std::path::PathBuf;
        let path = PathBuf::from("./keys_real.json");
        let mut api = Coinnect::new_from_file(Exchange::Bitstamp, "account_bitstamp", path);
        let result = api.return_balances(Pair::BTC_USD).unwrap();
        let result_looking_for_usd = result.clone();
        let result_looking_for_btc = result.clone();
        let result_looking_for_fee = result.clone();

        assert!(result_looking_for_usd.contains_key("usd_balance"));
        assert!(result_looking_for_btc.contains_key("btc_balance"));
        assert!(result_looking_for_fee.contains_key("fee"));
    }
}
<|endoftext|>


<commit_before>extern crate to;

use std::env;
use std::path::PathBuf;
use to::cli::Action;
use to::cli;

fn run(mut args: Vec<&str>) -> cli::Options {
    args.insert(0, "to");
    let matches = cli::app().get_matches_from(args);
    cli::Options::new(matches)
}

#[test]
fn cli_defaults() {
    let options = run(vec![]);
    assert_eq!(options.verbose, false);
    assert_eq!(options.initialize, false);
    assert_eq!(options.name, None);
    assert_eq!(options.action, Action::Pathname);
}

#[test]
fn cli_name() {
    let options = run(vec!["foo"]);
    assert_eq!(options.action, Action::Pathname);
    assert_eq!(options.name, Some(String::from("foo")));

    let options = run(vec!["Foo"]);
    assert_eq!(options.action, Action::Pathname);
    assert_eq!(options.name, Some(String::from("foo")));

    let options = run(vec!["foo/"]);
    assert_eq!(options.name, Some(String::from("foo")));
}

#[test]
fn cli_path() {
    let options = run(vec!["project", "~/code/project"]);
    assert_eq!(options.path, Some(PathBuf::from("~/code/project")));
}

#[test]
fn cli_flag_verbose() {
    assert_eq!(run(vec![]).verbose, false);

    let options = run(vec!["--verbose"]);
    assert_eq!(options.verbose, true);

    let options = run(vec!["-v"]);
    assert_eq!(options.verbose, true);
}

#[test]
fn cli_flag_info() {
    let options = run(vec!["--info"]);
    assert_eq!(options.action, Action::Info);

    let options = run(vec!["-i"]);
    assert_eq!(options.action, Action::Info);
}

#[test]
fn cli_flag_save() {
    let options = run(vec!["--save"]);
    assert_eq!(options.action, Action::Save);

    let options = run(vec!["-s"]);
    assert_eq!(options.action, Action::Save);
}

#[test]
fn cli_flag_list() {
    let options = run(vec!["--list"]);
    assert_eq!(options.action, Action::List);

    let options = run(vec!["-l"]);
    assert_eq!(options.action, Action::List);
}

#[test]
fn cli_flag_delete() {
    let options = run(vec!["foo", "--delete"]);
    assert_eq!(options.action, Action::Delete);

    let options = run(vec!["foo", "-d"]);
    assert_eq!(options.action, Action::Delete);
}

#[test]
fn cli_flag_config_default() {
    let options = run(vec![]);
    let expected = env::home_dir().map(|mut home| {
        home.push(".to");
        home
    });

    assert_eq!(options.config, expected);
}

#[test]
fn cli_flag_config() {
    let options = run(vec!["--config", "~/whatever"]);
    let expected = PathBuf::from("~/whatever");

    assert_eq!(options.config, Some(expected));
}
<commit_msg>add test for --init<commit_after>extern crate to;

use std::env;
use std::path::PathBuf;
use to::cli::Action;
use to::cli;

fn run(mut args: Vec<&str>) -> cli::Options {
    args.insert(0, "to");
    let matches = cli::app().get_matches_from(args);
    cli::Options::new(matches)
}

#[test]
fn cli_defaults() {
    let options = run(vec![]);
    assert_eq!(options.verbose, false);
    assert_eq!(options.initialize, false);
    assert_eq!(options.name, None);
    assert_eq!(options.action, Action::Pathname);
}

#[test]
fn cli_flag_init() {
    let options = run(vec!["--init"]);
    assert_eq!(options.initialize, true);
}

#[test]
fn cli_name() {
    let options = run(vec!["foo"]);
    assert_eq!(options.action, Action::Pathname);
    assert_eq!(options.name, Some(String::from("foo")));

    let options = run(vec!["Foo"]);
    assert_eq!(options.action, Action::Pathname);
    assert_eq!(options.name, Some(String::from("foo")));

    let options = run(vec!["foo/"]);
    assert_eq!(options.name, Some(String::from("foo")));
}

#[test]
fn cli_path() {
    let options = run(vec!["project", "~/code/project"]);
    assert_eq!(options.path, Some(PathBuf::from("~/code/project")));
}

#[test]
fn cli_flag_verbose() {
    assert_eq!(run(vec![]).verbose, false);

    let options = run(vec!["--verbose"]);
    assert_eq!(options.verbose, true);

    let options = run(vec!["-v"]);
    assert_eq!(options.verbose, true);
}

#[test]
fn cli_flag_info() {
    let options = run(vec!["--info"]);
    assert_eq!(options.action, Action::Info);

    let options = run(vec!["-i"]);
    assert_eq!(options.action, Action::Info);
}

#[test]
fn cli_flag_save() {
    let options = run(vec!["--save"]);
    assert_eq!(options.action, Action::Save);

    let options = run(vec!["-s"]);
    assert_eq!(options.action, Action::Save);
}

#[test]
fn cli_flag_list() {
    let options = run(vec!["--list"]);
    assert_eq!(options.action, Action::List);

    let options = run(vec!["-l"]);
    assert_eq!(options.action, Action::List);
}

#[test]
fn cli_flag_delete() {
    let options = run(vec!["foo", "--delete"]);
    assert_eq!(options.action, Action::Delete);

    let options = run(vec!["foo", "-d"]);
    assert_eq!(options.action, Action::Delete);
}

#[test]
fn cli_flag_config_default() {
    let options = run(vec![]);
    let expected = env::home_dir().map(|mut home| {
        home.push(".to");
        home
    });

    assert_eq!(options.config, expected);
}

#[test]
fn cli_flag_config() {
    let options = run(vec!["--config", "~/whatever"]);
    let expected = PathBuf::from("~/whatever");

    assert_eq!(options.config, Some(expected));
}
<|endoftext|>


<commit_before>extern crate gluon_language_server;
extern crate debugserver_types;
extern crate languageserver_types;

extern crate jsonrpc_core;
extern crate serde_json;
extern crate serde;
extern crate url;

#[macro_use]
extern crate lazy_static;

#[allow(dead_code)]
mod support;

use std::net::TcpStream;
use std::path::PathBuf;
use std::process::Command;
use std::io::{BufRead, BufReader, Write};
use std::sync::Mutex;

use serde_json::{Value, from_str};

use debugserver_types::*;

use gluon_language_server::rpc::read_message;

macro_rules! request {
    ($stream: expr, $id: ident, $command: expr, $seq: expr, $expr: expr) => {
        let request = $id {
            arguments: $expr,
            command: $command.to_string(),
            seq: { $seq += 1; $seq },
            type_: "request".into(),
        };
        support::write_message($stream, request).unwrap();
    }
}

lazy_static! {
    static ref PORT: Mutex<i32> = Mutex::new(4711);
}

fn run_debugger<F>(f: F)
    where F: FnOnce(&mut i64, &TcpStream, &mut BufReader<&TcpStream>),
{
    let port = {
        let mut port = PORT.lock().unwrap();
        *port += 1;
        *port
    };
    let path = PathBuf::from(::std::env::args().next().unwrap());
    let debugger = path.parent()
        .and_then(|path| path.parent())
        .expect("debugger executable")
        .join("debugger");

    let mut child = Command::new(&debugger)
        .arg(port.to_string())
        .spawn()
        .unwrap_or_else(|_| panic!("Expected exe: {}", debugger.display()));

    let stream = TcpStream::connect(&format!("localhost:{}", port)[..]).unwrap();

    let mut seq = 0;
    let mut read = BufReader::new(&stream);

    request! {
        &stream,
        InitializeRequest,
        "initialize",
        seq,
        InitializeRequestArguments {
            adapter_id: "".into(),
            columns_start_at_1: None,
            lines_start_at_1: None,
            path_format: None,
            supports_run_in_terminal_request: None,
            supports_variable_paging: None,
            supports_variable_type: None,
        }
    };

    let _: InitializedEvent = expect_message(&mut read);

    let initialize_response: InitializeResponse = expect_message(&mut read);
    assert!(initialize_response.success);

    f(&mut seq, &stream, &mut read);

    request! {
        &stream,
        DisconnectRequest,
        "disconnect",
        seq,
        None
    };

    child.wait().unwrap();
}

fn launch<W>(stream: W, seq: &mut i64, program: &str)
    where W: Write,
{
    request! {
        stream,
        Request,
        "launch",
        *seq,
        Some(Value::Object(vec![("program".to_string(),
                                    Value::String(program.to_string()))]
                                .into_iter()
                                .collect()))
    };
}

fn expect_message<M, R>(read: R) -> M
    where M: serde::Deserialize,
          R: BufRead,
{
    let value = read_message(read).unwrap().unwrap();
    from_str(&value).unwrap()
}

#[test]
fn launch_program() {
    run_debugger(|seq, stream, mut read| {
        launch(stream, seq, "tests/main.glu");

        let launch_response: LaunchResponse = expect_message(&mut read);
        assert_eq!(launch_response.request_seq, *seq);
        assert!(launch_response.success);

        request! {
            stream,
            ConfigurationDoneRequest,
            "configurationDone",
            *seq,
            None
        };
        let _: ConfigurationDoneResponse = expect_message(&mut read);

        let _: TerminatedEvent = expect_message(&mut read);
    });
}

#[test]
fn infinite_loops_are_terminated() {
    run_debugger(|seq, stream, mut read| {
        launch(stream, seq, "tests/infinite_loop.glu");

        let launch_response: LaunchResponse = expect_message(&mut read);
        assert_eq!(launch_response.request_seq, *seq);
        assert!(launch_response.success);

        request! {
            stream,
            ConfigurationDoneRequest,
            "configurationDone",
            *seq,
            None
        };
        let _: ConfigurationDoneResponse = expect_message(&mut read);
    });
}

#[test]
fn pause() {
    run_debugger(|seq, stream, mut read| {
        launch(stream, seq, "tests/infinite_loop.glu");

        let launch_response: LaunchResponse = expect_message(&mut read);
        assert_eq!(launch_response.request_seq, *seq);
        assert!(launch_response.success);

        request! {
            stream,
            ConfigurationDoneRequest,
            "configurationDone",
            *seq,
            None
        };
        let _: ConfigurationDoneResponse = expect_message(&mut read);

        request! {
            stream,
            PauseRequest,
            "pause",
            *seq,
            PauseArguments { thread_id: 0, }
        };
        let _: PauseResponse = expect_message(&mut read);

        let _: StoppedEvent = expect_message(&mut read);

        request! {
            stream,
            ContinueRequest,
            "continue",
            *seq,
            ContinueArguments { thread_id: 0, }
        };
        let _: ContinueResponse = expect_message(&mut read);
    });
}
<commit_msg>feat: Handle step requests<commit_after>extern crate gluon_language_server;
extern crate debugserver_types;
extern crate languageserver_types;

extern crate jsonrpc_core;
extern crate serde_json;
extern crate serde;
extern crate url;

#[macro_use]
extern crate lazy_static;

#[allow(dead_code)]
mod support;

use std::net::TcpStream;
use std::path::PathBuf;
use std::process::Command;
use std::io::{BufRead, BufReader, Write};
use std::sync::Mutex;

use serde_json::{Value, from_str};

use debugserver_types::*;

use gluon_language_server::rpc::read_message;

macro_rules! request {
    ($stream: expr, $id: ident, $command: expr, $seq: expr, $expr: expr) => {
        let request = $id {
            arguments: $expr,
            command: $command.to_string(),
            seq: { $seq += 1; $seq },
            type_: "request".into(),
        };
        support::write_message($stream, request).unwrap();
    }
}

macro_rules! expect_response {
    ($read: expr, $typ: ty, $name: expr) => { {
        let msg: $typ = expect_message(&mut $read);
        assert_eq!(msg.command, $name);
        msg
    } }
}

macro_rules! expect_event {
    ($read: expr, $typ: ty, $event: expr) => { {
        let event: $typ = expect_message(&mut $read);
        assert_eq!(event.event, $event);
        event
    } }
}

lazy_static! {
    static ref PORT: Mutex<i32> = Mutex::new(4711);
}

fn run_debugger<F>(f: F)
    where F: FnOnce(&mut i64, &TcpStream, &mut BufReader<&TcpStream>),
{
    let port = {
        let mut port = PORT.lock().unwrap();
        *port += 1;
        *port
    };
    let path = PathBuf::from(::std::env::args().next().unwrap());
    let debugger = path.parent()
        .and_then(|path| path.parent())
        .expect("debugger executable")
        .join("debugger");

    let mut child = Command::new(&debugger)
        .arg(port.to_string())
        .spawn()
        .unwrap_or_else(|_| panic!("Expected exe: {}", debugger.display()));

    let stream = TcpStream::connect(&format!("localhost:{}", port)[..]).unwrap();

    let mut seq = 0;
    let mut read = BufReader::new(&stream);

    request! {
        &stream,
        InitializeRequest,
        "initialize",
        seq,
        InitializeRequestArguments {
            adapter_id: "".into(),
            columns_start_at_1: None,
            lines_start_at_1: None,
            path_format: None,
            supports_run_in_terminal_request: None,
            supports_variable_paging: None,
            supports_variable_type: None,
        }
    };

    let _: InitializedEvent = expect_message(&mut read);

    let initialize_response: InitializeResponse = expect_message(&mut read);
    assert!(initialize_response.success);

    f(&mut seq, &stream, &mut read);

    request! {
        &stream,
        DisconnectRequest,
        "disconnect",
        seq,
        None
    };
    expect_response!(read, DisconnectResponse, "disconnect");

    child.wait().unwrap();
}

fn launch<W>(stream: W, seq: &mut i64, program: &str)
    where W: Write,
{
    request! {
        stream,
        Request,
        "launch",
        *seq,
        Some(Value::Object(vec![("program".to_string(),
                                    Value::String(program.to_string()))]
                                .into_iter()
                                .collect()))
    };
}

fn request_debug_info(seq: &mut i64,
                      stream: &TcpStream,
                      mut read: &mut BufReader<&TcpStream>)
                      -> (StackTraceResponse, ScopesResponse, VariablesResponse) {
    request! {
        stream,
        ThreadsRequest,
        "threads",
        *seq,
        None
    };
    expect_response!(read, ThreadsResponse, "threads");

    request! {
        stream,
        StackTraceRequest,
        "stackTrace",
        *seq,
        StackTraceArguments {
            levels: Some(20),
            start_frame: None,
            thread_id: 1,
        }
    };
    let trace = expect_response!(read, StackTraceResponse, "stackTrace");

    request! {
        stream,
        ScopesRequest,
        "scopes",
        *seq,
        ScopesArguments { frame_id: 0 }
    };
    let scopes = expect_response!(read, ScopesResponse, "scopes");

    request! {
        stream,
        VariablesRequest,
        "variables",
        *seq,
        VariablesArguments {
            count: None,
            filter: None,
            start: None,
            variables_reference: 1
        }
    };
    let variables = expect_response!(read, VariablesResponse, "variables");
    (trace, scopes, variables)
}

fn expect_message<M, R>(read: R) -> M
    where M: serde::Deserialize,
          R: BufRead,
{
    let value = read_message(read).unwrap().unwrap();
    from_str(&value).unwrap_or_else(|err| {
        panic!("{} in message:\n{}", err, value);
    })
}

#[test]
fn launch_program() {
    run_debugger(|seq, stream, mut read| {
        launch(stream, seq, "tests/main.glu");

        let launch_response: LaunchResponse = expect_message(&mut read);
        assert_eq!(launch_response.request_seq, *seq);
        assert!(launch_response.success);

        request! {
            stream,
            ConfigurationDoneRequest,
            "configurationDone",
            *seq,
            None
        };
        let _: ConfigurationDoneResponse = expect_message(&mut read);

        let _: TerminatedEvent = expect_message(&mut read);
    });
}

#[test]
fn infinite_loops_are_terminated() {
    run_debugger(|seq, stream, mut read| {
        launch(stream, seq, "tests/infinite_loop.glu");

        let launch_response: LaunchResponse = expect_message(&mut read);
        assert_eq!(launch_response.request_seq, *seq);
        assert!(launch_response.success);

        request! {
            stream,
            ConfigurationDoneRequest,
            "configurationDone",
            *seq,
            None
        };
        let _: ConfigurationDoneResponse = expect_message(&mut read);
    });
}

#[test]
fn pause() {
    run_debugger(|seq, stream, mut read| {
        launch(stream, seq, "tests/infinite_loop.glu");

        let launch_response: LaunchResponse = expect_message(&mut read);
        assert_eq!(launch_response.request_seq, *seq);
        assert!(launch_response.success);

        request! {
            stream,
            ConfigurationDoneRequest,
            "configurationDone",
            *seq,
            None
        };
        let _: ConfigurationDoneResponse = expect_message(&mut read);

        request! {
            stream,
            PauseRequest,
            "pause",
            *seq,
            PauseArguments { thread_id: 0, }
        };
        let _: PauseResponse = expect_message(&mut read);

        let _: StoppedEvent = expect_message(&mut read);

        request! {
            stream,
            ContinueRequest,
            "continue",
            *seq,
            ContinueArguments { thread_id: 0, }
        };
        let _: ContinueResponse = expect_message(&mut read);
    });
}

#[test]
fn breakpoints() {
    run_debugger(|seq, stream, mut read| {
        launch(stream, seq, "tests/main.glu");

        let launch_response = expect_response!(read, LaunchResponse, "launch");
        assert_eq!(launch_response.request_seq, *seq);
        assert!(launch_response.success);

        request! {
            stream,
            SetBreakpointsRequest,
            "setBreakpoints",
            *seq,
            SetBreakpointsArguments {
                breakpoints: Some(vec![
                    SourceBreakpoint {
                        column: None,
                        condition: None,
                        hit_condition: None,
                        line: 1,
                    },
                    SourceBreakpoint {
                        column: None,
                        condition: None,
                        hit_condition: None,
                        line: 14,
                    },
                ]),
                lines: None,
                source: Source {
                    path: Some("tests/main.glu".into()),
                    .. Source::default()
                },
                source_modified: None,
            }
        };
        expect_response!(read, SetBreakpointsResponse, "setBreakpoints");

        request! {
            stream,
            ConfigurationDoneRequest,
            "configurationDone",
            *seq,
            None
        };
        expect_response!(read, ConfigurationDoneResponse, "configurationDone");

        let stopped = expect_event!(read, StoppedEvent, "stopped");
        assert_eq!(stopped.body.reason, "breakpoint");

        request! {
            stream,
            ContinueRequest,
            "continue",
            *seq,
            ContinueArguments { thread_id: 0, }
        };
        expect_response!(read, ContinueResponse, "continue");

        let stopped = expect_event!(read, StoppedEvent, "stopped");
        assert_eq!(stopped.body.reason, "breakpoint");

        request! {
            stream,
            ContinueRequest,
            "continue",
            *seq,
            ContinueArguments { thread_id: 0, }
        };
        expect_response!(read, ContinueResponse, "continue");

        expect_event!(read, TerminatedEvent, "terminated");
    });
}

#[test]
fn step_in() {
    run_debugger(|seq, stream, mut read| {
        launch(stream, seq, "tests/main.glu");

        let launch_response = expect_response!(read, LaunchResponse, "launch");
        assert_eq!(launch_response.request_seq, *seq);
        assert!(launch_response.success);

        request! {
            stream,
            SetBreakpointsRequest,
            "setBreakpoints",
            *seq,
            SetBreakpointsArguments {
                breakpoints: Some(vec![
                    SourceBreakpoint {
                        column: None,
                        condition: None,
                        hit_condition: None,
                        line: 14,
                    },
                ]),
                lines: None,
                source: Source {
                    path: Some("tests/main.glu".into()),
                    .. Source::default()
                },
                source_modified: None,
            }
        };
        expect_response!(read, SetBreakpointsResponse, "setBreakpoints");

        request! {
            stream,
            ConfigurationDoneRequest,
            "configurationDone",
            *seq,
            None
        };
        expect_response!(read, ConfigurationDoneResponse, "configurationDone");

        let stopped = expect_event!(read, StoppedEvent, "stopped");
        assert_eq!(stopped.body.reason, "breakpoint");

        request! {
            stream,
            StepInRequest,
            "stepIn",
            *seq,
            StepInArguments {
                target_id: None,
                thread_id: 0
            }
        };
        expect_response!(read, StepInResponse, "stepIn");
        let stopped = expect_event!(read, StoppedEvent, "stopped");
        assert_eq!(stopped.body.reason, "step");

        let (trace, _, _) = request_debug_info(seq, stream, read);
        let frames = &trace.body.stack_frames;
        assert_eq!(frames.len(), 2);
        assert_eq!(frames[0].line, 6);
        assert_eq!(frames[0].name, "test");
        assert_eq!(frames[1].line, 14);

        request! {
            stream,
            ContinueRequest,
            "continue",
            *seq,
            ContinueArguments { thread_id: 0, }
        };
        expect_response!(read, ContinueResponse, "continue");

        expect_event!(read, TerminatedEvent, "terminated");
    });
}

#[test]
fn step_out() {
    run_debugger(|seq, stream, mut read| {
        launch(stream, seq, "tests/main.glu");

        let launch_response = expect_response!(read, LaunchResponse, "launch");
        assert_eq!(launch_response.request_seq, *seq);
        assert!(launch_response.success);

        request! {
            stream,
            SetBreakpointsRequest,
            "setBreakpoints",
            *seq,
            SetBreakpointsArguments {
                breakpoints: Some(vec![
                    SourceBreakpoint {
                        column: None,
                        condition: None,
                        hit_condition: None,
                        line: 6,
                    },
                ]),
                lines: None,
                source: Source {
                    path: Some("tests/main.glu".into()),
                    .. Source::default()
                },
                source_modified: None,
            }
        };
        expect_response!(read, SetBreakpointsResponse, "setBreakpoints");

        request! {
            stream,
            ConfigurationDoneRequest,
            "configurationDone",
            *seq,
            None
        };
        expect_response!(read, ConfigurationDoneResponse, "configurationDone");

        let stopped = expect_event!(read, StoppedEvent, "stopped");
        assert_eq!(stopped.body.reason, "breakpoint");

        request! {
            stream,
            StepOutRequest,
            "stepOut",
            *seq,
            StepOutArguments {
                thread_id: 0
            }
        };
        expect_response!(read, StepOutResponse, "stepOut");
        let stopped = expect_event!(read, StoppedEvent, "stopped");
        assert_eq!(stopped.body.reason, "step");

        let (trace, _, _) = request_debug_info(seq, stream, read);
        let frames = &trace.body.stack_frames;
        assert_eq!(frames.len(), 1);
        assert_eq!(frames[0].line, 15);

        request! {
            stream,
            ContinueRequest,
            "continue",
            *seq,
            ContinueArguments { thread_id: 0, }
        };
        expect_response!(read, ContinueResponse, "continue");

        expect_event!(read, TerminatedEvent, "terminated");
    });
}

#[test]
fn step_over() {
    run_debugger(|seq, stream, mut read| {
        launch(stream, seq, "tests/main.glu");

        let launch_response = expect_response!(read, LaunchResponse, "launch");
        assert_eq!(launch_response.request_seq, *seq);
        assert!(launch_response.success);

        request! {
            stream,
            SetBreakpointsRequest,
            "setBreakpoints",
            *seq,
            SetBreakpointsArguments {
                breakpoints: Some(vec![
                    SourceBreakpoint {
                        column: None,
                        condition: None,
                        hit_condition: None,
                        line: 14,
                    },
                ]),
                lines: None,
                source: Source {
                    path: Some("tests/main.glu".into()),
                    .. Source::default()
                },
                source_modified: None,
            }
        };
        expect_response!(read, SetBreakpointsResponse, "setBreakpoints");

        request! {
            stream,
            ConfigurationDoneRequest,
            "configurationDone",
            *seq,
            None
        };
        expect_response!(read, ConfigurationDoneResponse, "configurationDone");

        let stopped = expect_event!(read, StoppedEvent, "stopped");
        assert_eq!(stopped.body.reason, "breakpoint");

        request! {
            stream,
            NextRequest,
            "next",
            *seq,
            NextArguments {
                thread_id: 0
            }
        };
        expect_response!(read, StepOutResponse, "next");
        let stopped = expect_event!(read, StoppedEvent, "stopped");
        assert_eq!(stopped.body.reason, "step");

        let (trace, _, _) = request_debug_info(seq, stream, read);
        let frames = &trace.body.stack_frames;
        assert_eq!(frames.len(), 1);
        assert_eq!(frames[0].line, 15);

        request! {
            stream,
            ContinueRequest,
            "continue",
            *seq,
            ContinueArguments { thread_id: 0, }
        };
        expect_response!(read, ContinueResponse, "continue");

        expect_event!(read, TerminatedEvent, "terminated");
    });
}
<|endoftext|>


<commit_before>#![allow(clippy::manual_assert)]

mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "e95b10ba4ac4564ed25f7eef143e3182c33b3902";

#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
    // TODO: trait bound with associated constant constraint:
    // where T: Trait<N = 3usize>
    "src/test/ui/associated-consts/assoc-const.rs",

    // TODO: trailing where-clause on impl associated type:
    // impl<T> Trait for Ty<T> { type Assoc<'a> = T where T: 'a; }
    "src/test/ui/generic-associated-types/collections.rs",
    "src/test/ui/generic-associated-types/construct_with_other_type.rs",
    "src/test/ui/generic-associated-types/impl_bounds_ok.rs",
    "src/test/ui/generic-associated-types/issue-76826.rs",
    "src/test/ui/generic-associated-types/issue-88287.rs",
    "src/test/ui/generic-associated-types/issue-91139.rs",
    "src/test/ui/generic-associated-types/issue-92280.rs",
    "src/test/ui/generic-associated-types/iterable.rs",
    "src/test/ui/generic-associated-types/streaming_iterator.rs",

    // TODO: impl ~const T {}
    // https://github.com/dtolnay/syn/issues/1051
    "src/test/ui/rfc-2632-const-trait-impl/syntax.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/early/closing-args-token.rs",
    "src/test/ui/const-generics/early/const-expression-parameter.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",
    "src/tools/rustfmt/tests/source/trait.rs",
    "src/tools/rustfmt/tests/target/trait.rs",

    // Excessive nesting
    "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs",

    // Testing rustfmt on invalid syntax
    "src/tools/rustfmt/tests/coverage/target/comments.rs",
    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
    "src/tools/rustfmt/tests/parser/issue_4418.rs",
    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/source/type.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/target/type.rs",

    // Clippy lint lists represented as expressions
    "src/tools/clippy/clippy_lints/src/lib.deprecated.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_all.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_cargo.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_complexity.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_correctness.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_internal.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_lints.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_nursery.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_perf.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_restriction.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_style.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs",

    // Not actually test cases
    "src/test/rustdoc-ui/test-compile-fail2.rs",
    "src/test/rustdoc-ui/test-compile-fail3.rs",
    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
    "src/test/ui/macros/include-single-expr-helper.rs",
    "src/test/ui/macros/include-single-expr-helper-1.rs",
    "src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map_or(true, |e| e != "rs") {
        return false;
    }

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
        return false;
    }

    if path.starts_with("src/test/ui") {
        let stderr_path = entry.path().with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE.contains(&path)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE {
        if !test_src.join(exclude).exists() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<commit_msg>Attach issue to remaining test suite TODOs<commit_after>#![allow(clippy::manual_assert)]

mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "e95b10ba4ac4564ed25f7eef143e3182c33b3902";

#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
    // TODO: trait bound with associated constant constraint:
    // where T: Trait<N = 3usize>
    // https://github.com/dtolnay/syn/issues/1138
    "src/test/ui/associated-consts/assoc-const.rs",

    // TODO: trailing where-clause on impl associated type:
    // impl<T> Trait for Ty<T> { type Assoc<'a> = T where T: 'a; }
    // https://github.com/dtolnay/syn/issues/1071
    "src/test/ui/generic-associated-types/collections.rs",
    "src/test/ui/generic-associated-types/construct_with_other_type.rs",
    "src/test/ui/generic-associated-types/impl_bounds_ok.rs",
    "src/test/ui/generic-associated-types/issue-76826.rs",
    "src/test/ui/generic-associated-types/issue-88287.rs",
    "src/test/ui/generic-associated-types/issue-91139.rs",
    "src/test/ui/generic-associated-types/issue-92280.rs",
    "src/test/ui/generic-associated-types/iterable.rs",
    "src/test/ui/generic-associated-types/streaming_iterator.rs",

    // TODO: impl ~const T {}
    // https://github.com/dtolnay/syn/issues/1051
    "src/test/ui/rfc-2632-const-trait-impl/syntax.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/early/closing-args-token.rs",
    "src/test/ui/const-generics/early/const-expression-parameter.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",
    "src/tools/rustfmt/tests/source/trait.rs",
    "src/tools/rustfmt/tests/target/trait.rs",

    // Excessive nesting
    "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs",

    // Testing rustfmt on invalid syntax
    "src/tools/rustfmt/tests/coverage/target/comments.rs",
    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
    "src/tools/rustfmt/tests/parser/issue_4418.rs",
    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/source/type.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/target/type.rs",

    // Clippy lint lists represented as expressions
    "src/tools/clippy/clippy_lints/src/lib.deprecated.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_all.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_cargo.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_complexity.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_correctness.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_internal.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_lints.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_nursery.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_perf.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_restriction.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_style.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs",

    // Not actually test cases
    "src/test/rustdoc-ui/test-compile-fail2.rs",
    "src/test/rustdoc-ui/test-compile-fail3.rs",
    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
    "src/test/ui/macros/include-single-expr-helper.rs",
    "src/test/ui/macros/include-single-expr-helper-1.rs",
    "src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map_or(true, |e| e != "rs") {
        return false;
    }

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
        return false;
    }

    if path.starts_with("src/test/ui") {
        let stderr_path = entry.path().with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE.contains(&path)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE {
        if !test_src.join(exclude).exists() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<|endoftext|>


<commit_before>extern crate herder;
extern crate serde_json;

use herder::api::v1::{
    Account,
    Application,
    Attachment,
    Card,
    Context,
    Error,
    Instance,
    Mention,
    Notification,
    Relationship,
    Report,
    Results,
    Status,
    Tag
};

#[test]
fn account_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn application_deserialize_from_json() {
    let ojson = r#"{
                    "name": "MYNAME",
                    "website": "MYURI"
                 }"#;
    let application: Application = serde_json::from_str(ojson).unwrap();
    assert_eq!(application, Application {
                        name: String::from("MYNAME"),
                        website: Some(String::from("MYURI"))
    });
}

#[test]
fn attachment_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "type": "video",
                    "url": "MYURL",
                    "remote_url": "MYURL",
                    "preview_url": "MYURL",
                    "text_url": "MYURL"
                 }"#;
    let attachment: Attachment = serde_json::from_str(ojson).unwrap();
    assert_eq!(attachment, Attachment {
                        attachment_id: 1234,
                        attachment_type: String::from("video"),
                        url: String::from("MYURL"),
                        remote_url: String::from("MYURL"),
                        preview_url: String::from("MYURL"),
                        text_url: String::from("MYURL")
    });
}

#[test]
fn card_deserialize_from_json() {
    let ojson = r#"{
                    "url": "MYURL",
                    "title": "My Title",
                    "description": "My description",
                    "image": "MYIMG.png"
                 }"#;
    let card: Card = serde_json::from_str(ojson).unwrap();
    assert_eq!(card, Card {
                        url: String::from("MYURL"),
                        title: String::from("My Title"),
                        description: String::from("My description"),
                        image: String::from("MYIMG.png")
    });
}

#[test]
fn context_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn error_deserialize_from_json() {
    let ojson = r#"{
                    "error": "Error message"
                 }"#;
    let error: Error = serde_json::from_str(ojson).unwrap();
    assert_eq!(error, Error {
                        error: String::from("Error message")
    });
}

#[test]
fn instance_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn mention_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn notification_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn relationship_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn report_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "action_taken": "Some action taken"
                 }"#;
    let report: Report = serde_json::from_str(ojson).unwrap();
    assert_eq!(report, Report {
                        report_id: 1234,
                        action_taken: String::from("Some action taken")
    });
}

#[test]
fn results_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn status_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn tag_deserialize_from_json() {
    let ojson = r#"{
                    "name": "rustlang",
                    "url": "MYURL"
                 }"#;
    let tag: Tag = serde_json::from_str(ojson).unwrap();
    assert_eq!(tag, Tag {
                        name: String::from("rustlang"),
                        url: String::from("MYURL")
    });
}
<commit_msg>more tests of simple API entities<commit_after>extern crate herder;
extern crate serde_json;

use herder::api::v1::{
    Account,
    Application,
    Attachment,
    Card,
    Context,
    Error,
    Instance,
    Mention,
    Notification,
    Relationship,
    Report,
    Results,
    Status,
    Tag
};

#[test]
fn account_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn application_deserialize_from_json() {
    let ojson = r#"{
                    "name": "MYNAME",
                    "website": "MYURI"
                 }"#;
    let application: Application = serde_json::from_str(ojson).unwrap();
    assert_eq!(application, Application {
                        name: String::from("MYNAME"),
                        website: Some(String::from("MYURI"))
    });
}

#[test]
fn attachment_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "type": "video",
                    "url": "MYURL",
                    "remote_url": "MYURL",
                    "preview_url": "MYURL",
                    "text_url": "MYURL"
                 }"#;
    let attachment: Attachment = serde_json::from_str(ojson).unwrap();
    assert_eq!(attachment, Attachment {
                        attachment_id: 1234,
                        attachment_type: String::from("video"),
                        url: String::from("MYURL"),
                        remote_url: String::from("MYURL"),
                        preview_url: String::from("MYURL"),
                        text_url: String::from("MYURL")
    });
}

#[test]
fn card_deserialize_from_json() {
    let ojson = r#"{
                    "url": "MYURL",
                    "title": "My Title",
                    "description": "My description",
                    "image": "MYIMG.png"
                 }"#;
    let card: Card = serde_json::from_str(ojson).unwrap();
    assert_eq!(card, Card {
                        url: String::from("MYURL"),
                        title: String::from("My Title"),
                        description: String::from("My description"),
                        image: String::from("MYIMG.png")
    });
}

#[test]
fn context_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn error_deserialize_from_json() {
    let ojson = r#"{
                    "error": "Error message"
                 }"#;
    let error: Error = serde_json::from_str(ojson).unwrap();
    assert_eq!(error, Error {
                        error: String::from("Error message")
    });
}

#[test]
fn instance_deserialize_from_json() {
    let ojson = r#"{
                    "url": "MYURL",
                    "title": "My Title",
                    "description": "My description",
                    "email": "MYEMAIL"
                 }"#;
    let instance: Instance = serde_json::from_str(ojson).unwrap();
    assert_eq!(instance, Instance {
                        url: String::from("MYURL"),
                        title: String::from("My Title"),
                        description: String::from("My description"),
                        email: String::from("MYEMAIL")
    });
}

#[test]
fn mention_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "url": "MYURL",
                    "username": "MYUSERNAME",
                    "acct": "MYUSERNAME@REMOTEDOMAIN"
                 }"#;
    let mention: Mention = serde_json::from_str(ojson).unwrap();
    assert_eq!(mention, Mention {
                        mention_id: 1234,
                        url: String::from("MYURL"),
                        username: String::from("MYUSERNAME"),
                        acct: String::from("MYUSERNAME@REMOTEDOMAIN")
    });
}

#[test]
fn notification_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn relationship_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "following": true,
                    "followed_by": true,
                    "blocking": true,
                    "muting": true,
                    "requested": true
                 }"#;
    let relationship: Relationship = serde_json::from_str(ojson).unwrap();
    assert_eq!(relationship, Relationship {
                        relationship_id: 1234,
                        following: true,
                        followed_by: true,
                        blocking: true,
                        muting: true,
                        requested: true
    });
}

#[test]
fn report_deserialize_from_json() {
    let ojson = r#"{
                    "id": 1234,
                    "action_taken": "Some action taken"
                 }"#;
    let report: Report = serde_json::from_str(ojson).unwrap();
    assert_eq!(report, Report {
                        report_id: 1234,
                        action_taken: String::from("Some action taken")
    });
}

#[test]
fn results_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn status_deserialize_from_json() {
    unimplemented!();
}

#[test]
fn tag_deserialize_from_json() {
    let ojson = r#"{
                    "name": "rustlang",
                    "url": "MYURL"
                 }"#;
    let tag: Tag = serde_json::from_str(ojson).unwrap();
    assert_eq!(tag, Tag {
                        name: String::from("rustlang"),
                        url: String::from("MYURL")
    });
}
<|endoftext|>