<commit_before>extern crate atom_syndication as atom;

use std::fs::File;
use std::io::BufReader;

use crate::atom::extension::ExtensionMap;
use crate::atom::{Feed, Text};

macro_rules! feed {
    ($f:expr) => {{
        let file = File::open($f).unwrap();
        let reader = BufReader::new(file);
        Feed::read_from(reader).unwrap()
    }};
}

#[test]
fn read_feed() {
    let feed = feed!("tests/data/feed.xml");
    assert_eq!(feed.title(), "Feed Title");
    assert_eq!(feed.id(), "urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6");
    assert_eq!(feed.updated().to_rfc3339(), "2017-06-03T15:15:44-05:00");
    assert_eq!(feed.icon(), Some("http://example.com/icon.png"));
    assert_eq!(feed.logo(), Some("http://example.com/logo.png"));
    assert_eq!(feed.rights().map(Text::as_str), Some("© 2017 John Doe"));
    assert_eq!(feed.subtitle().map(Text::as_str), Some("Feed subtitle"));
    assert_eq!(feed.authors().len(), 2);
    assert_eq!(feed.categories().len(), 2);
    assert_eq!(feed.contributors().len(), 2);
    assert!(feed.generator().is_some());
    assert_eq!(feed.links().len(), 2);
}

#[test]
fn read_entry() {
    let feed = feed!("tests/data/entry.xml");
    assert_eq!(feed.entries().len(), 1);

    let entry = feed.entries().first().unwrap();
    assert_eq!(entry.title(), "Entry Title");
    assert_eq!(entry.id(), "http://example.com/article/1");
    assert_eq!(entry.updated().to_rfc3339(), "2017-06-03T15:15:44-05:00");
    assert_eq!(entry.authors().len(), 2);
    assert_eq!(entry.categories().len(), 2);
    assert_eq!(entry.contributors().len(), 2);
    assert_eq!(entry.links().len(), 2);
    assert_eq!(
        entry.published().map(chrono::DateTime::to_rfc3339),
        Some("2017-06-01T15:15:44-05:00".to_string())
    );
    assert_eq!(entry.summary().map(Text::as_str), Some("Entry summary"));
    assert_eq!(entry.rights().map(Text::as_str), Some("© 2017 John Doe"));

    let content = entry.content().unwrap();
    assert_eq!(content.value(), Some("Entry content"));
}

#[test]
fn read_entry_with_non_standard_dates() {
    let feed = feed!("tests/data/entry_with_non_standard_dates.xml");
    assert_eq!(feed.entries().len(), 1);

    let entry = feed.entries().first().unwrap();
    assert_eq!(entry.title(), "Entry Title");
    assert_eq!(entry.id(), "http://example.com/article/1");
    assert_eq!(entry.updated().to_rfc3339(), "2017-06-03T15:15:44-05:00");
    assert_eq!(entry.authors().len(), 2);
    assert_eq!(entry.categories().len(), 2);
    assert_eq!(entry.contributors().len(), 2);
    assert_eq!(entry.links().len(), 2);
    assert_eq!(
        entry.published().map(chrono::DateTime::to_rfc3339),
        Some("2017-06-01T15:15:44-05:00".to_string())
    );
    assert_eq!(entry.summary().map(Text::as_str), Some("Entry summary"));
    assert_eq!(entry.rights().map(Text::as_str), Some("© 2017 John Doe"));

    let content = entry.content().unwrap();
    assert_eq!(content.value(), Some("Entry content"));
}

#[test]
fn read_category() {
    let feed = feed!("tests/data/category.xml");
    let category = feed.categories().first().unwrap();
    assert_eq!(category.term(), "technology");
    assert_eq!(category.scheme(), Some("http://example.com/scheme"));
    assert_eq!(category.label(), Some("Technology"));
}

#[test]
fn read_generator() {
    let feed = feed!("tests/data/generator.xml");
    let generator = feed.generator().unwrap();
    assert_eq!(generator.value(), "Example Generator");
    assert_eq!(generator.uri(), Some("http://example.com/generator"));
    assert_eq!(generator.version(), Some("1.0"));
}

#[test]
fn read_link() {
    let feed = feed!("tests/data/link.xml");
    let link = feed.links().first().unwrap();
    assert_eq!(link.rel(), "enclosure");
    assert_eq!(link.href(), "http://example.com/audio.mp3");
    assert_eq!(link.hreflang(), Some("en"));
    assert_eq!(link.mime_type(), Some("audio/mpeg"));
    assert_eq!(link.title(), Some("audio"));
    assert_eq!(link.length(), Some("1000"));
}

#[test]
fn read_person() {
    let feed = feed!("tests/data/person.xml");
    let person = feed.authors().first().unwrap();
    assert_eq!(person.name(), "John Doe");
    assert_eq!(person.email(), Some("johndoe@example.com"));
    assert_eq!(person.uri(), Some("http://example.com"));
}

#[test]
fn read_source() {
    let feed = feed!("tests/data/source.xml");

    let entry = feed.entries().first().unwrap();
    assert!(entry.source().is_some());

    let source = entry.source().unwrap();
    assert_eq!(source.title(), "Feed Title");
    assert_eq!(source.id(), "urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6");
    assert_eq!(source.updated().to_rfc3339(), "2017-06-03T15:15:44-05:00");
    assert_eq!(source.icon(), Some("http://example.com/icon.png"));
    assert_eq!(source.logo(), Some("http://example.com/logo.png"));
    assert_eq!(source.rights().map(Text::as_str), Some("© 2017 John Doe"));
    assert_eq!(source.subtitle().map(Text::as_str), Some("Feed subtitle"));
    assert_eq!(source.authors().len(), 2);
    assert_eq!(source.categories().len(), 2);
    assert_eq!(source.contributors().len(), 2);
    assert!(source.generator().is_some());
}

#[test]
fn read_extension() {
    let feed = feed!("tests/data/extension.xml");
    let entry = feed.entries().first().unwrap();

    assert_eq!(
        feed.namespaces().get("ext").map(String::as_str),
        Some("http://example.com")
    );

    let check_extensions = |extensions: &ExtensionMap| {
        assert!(extensions.contains_key("ext"));
        let map = extensions.get("ext").unwrap();

        assert!(map.contains_key("title"));
        let title = map.get("title").unwrap().first().unwrap();
        assert_eq!(title.value(), Some("Title"));
        assert_eq!(title.attrs().get("type").map(String::as_str), Some("text"));

        assert!(map.contains_key("parent"));
        let parent = map.get("parent").unwrap().first().unwrap();

        assert!(parent.children().contains_key("child"));
        let child = parent.children().get("child").unwrap().first().unwrap();
        assert_eq!(child.value(), Some("Child"));
    };

    check_extensions(feed.extensions());
    check_extensions(entry.extensions());
}
<commit_msg>Added error unit tests for FromXml<commit_after>extern crate atom_syndication as atom;

use std::fs::File;
use std::io::BufReader;

use atom::Error;

use crate::atom::extension::ExtensionMap;
use crate::atom::{Feed, Text};

macro_rules! feed {
    ($f:expr) => {{
        let file = File::open($f).unwrap();
        let reader = BufReader::new(file);
        Feed::read_from(reader).unwrap()
    }};
}

#[test]
fn read_feed() {
    let feed = feed!("tests/data/feed.xml");
    assert_eq!(feed.title(), "Feed Title");
    assert_eq!(feed.id(), "urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6");
    assert_eq!(feed.updated().to_rfc3339(), "2017-06-03T15:15:44-05:00");
    assert_eq!(feed.icon(), Some("http://example.com/icon.png"));
    assert_eq!(feed.logo(), Some("http://example.com/logo.png"));
    assert_eq!(feed.rights().map(Text::as_str), Some("© 2017 John Doe"));
    assert_eq!(feed.subtitle().map(Text::as_str), Some("Feed subtitle"));
    assert_eq!(feed.authors().len(), 2);
    assert_eq!(feed.categories().len(), 2);
    assert_eq!(feed.contributors().len(), 2);
    assert!(feed.generator().is_some());
    assert_eq!(feed.links().len(), 2);
}

#[test]
fn read_entry() {
    let feed = feed!("tests/data/entry.xml");
    assert_eq!(feed.entries().len(), 1);

    let entry = feed.entries().first().unwrap();
    assert_eq!(entry.title(), "Entry Title");
    assert_eq!(entry.id(), "http://example.com/article/1");
    assert_eq!(entry.updated().to_rfc3339(), "2017-06-03T15:15:44-05:00");
    assert_eq!(entry.authors().len(), 2);
    assert_eq!(entry.categories().len(), 2);
    assert_eq!(entry.contributors().len(), 2);
    assert_eq!(entry.links().len(), 2);
    assert_eq!(
        entry.published().map(chrono::DateTime::to_rfc3339),
        Some("2017-06-01T15:15:44-05:00".to_string())
    );
    assert_eq!(entry.summary().map(Text::as_str), Some("Entry summary"));
    assert_eq!(entry.rights().map(Text::as_str), Some("© 2017 John Doe"));

    let content = entry.content().unwrap();
    assert_eq!(content.value(), Some("Entry content"));
}

#[test]
fn read_entry_with_non_standard_dates() {
    let feed = feed!("tests/data/entry_with_non_standard_dates.xml");
    assert_eq!(feed.entries().len(), 1);

    let entry = feed.entries().first().unwrap();
    assert_eq!(entry.title(), "Entry Title");
    assert_eq!(entry.id(), "http://example.com/article/1");
    assert_eq!(entry.updated().to_rfc3339(), "2017-06-03T15:15:44-05:00");
    assert_eq!(entry.authors().len(), 2);
    assert_eq!(entry.categories().len(), 2);
    assert_eq!(entry.contributors().len(), 2);
    assert_eq!(entry.links().len(), 2);
    assert_eq!(
        entry.published().map(chrono::DateTime::to_rfc3339),
        Some("2017-06-01T15:15:44-05:00".to_string())
    );
    assert_eq!(entry.summary().map(Text::as_str), Some("Entry summary"));
    assert_eq!(entry.rights().map(Text::as_str), Some("© 2017 John Doe"));

    let content = entry.content().unwrap();
    assert_eq!(content.value(), Some("Entry content"));
}

#[test]
fn read_category() {
    let feed = feed!("tests/data/category.xml");
    let category = feed.categories().first().unwrap();
    assert_eq!(category.term(), "technology");
    assert_eq!(category.scheme(), Some("http://example.com/scheme"));
    assert_eq!(category.label(), Some("Technology"));
}

#[test]
fn read_generator() {
    let feed = feed!("tests/data/generator.xml");
    let generator = feed.generator().unwrap();
    assert_eq!(generator.value(), "Example Generator");
    assert_eq!(generator.uri(), Some("http://example.com/generator"));
    assert_eq!(generator.version(), Some("1.0"));
}

#[test]
fn read_link() {
    let feed = feed!("tests/data/link.xml");
    let link = feed.links().first().unwrap();
    assert_eq!(link.rel(), "enclosure");
    assert_eq!(link.href(), "http://example.com/audio.mp3");
    assert_eq!(link.hreflang(), Some("en"));
    assert_eq!(link.mime_type(), Some("audio/mpeg"));
    assert_eq!(link.title(), Some("audio"));
    assert_eq!(link.length(), Some("1000"));
}

#[test]
fn read_person() {
    let feed = feed!("tests/data/person.xml");
    let person = feed.authors().first().unwrap();
    assert_eq!(person.name(), "John Doe");
    assert_eq!(person.email(), Some("johndoe@example.com"));
    assert_eq!(person.uri(), Some("http://example.com"));
}

#[test]
fn read_source() {
    let feed = feed!("tests/data/source.xml");

    let entry = feed.entries().first().unwrap();
    assert!(entry.source().is_some());

    let source = entry.source().unwrap();
    assert_eq!(source.title(), "Feed Title");
    assert_eq!(source.id(), "urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6");
    assert_eq!(source.updated().to_rfc3339(), "2017-06-03T15:15:44-05:00");
    assert_eq!(source.icon(), Some("http://example.com/icon.png"));
    assert_eq!(source.logo(), Some("http://example.com/logo.png"));
    assert_eq!(source.rights().map(Text::as_str), Some("© 2017 John Doe"));
    assert_eq!(source.subtitle().map(Text::as_str), Some("Feed subtitle"));
    assert_eq!(source.authors().len(), 2);
    assert_eq!(source.categories().len(), 2);
    assert_eq!(source.contributors().len(), 2);
    assert!(source.generator().is_some());
}

#[test]
fn read_extension() {
    let feed = feed!("tests/data/extension.xml");
    let entry = feed.entries().first().unwrap();

    assert_eq!(
        feed.namespaces().get("ext").map(String::as_str),
        Some("http://example.com")
    );

    let check_extensions = |extensions: &ExtensionMap| {
        assert!(extensions.contains_key("ext"));
        let map = extensions.get("ext").unwrap();

        assert!(map.contains_key("title"));
        let title = map.get("title").unwrap().first().unwrap();
        assert_eq!(title.value(), Some("Title"));
        assert_eq!(title.attrs().get("type").map(String::as_str), Some("text"));

        assert!(map.contains_key("parent"));
        let parent = map.get("parent").unwrap().first().unwrap();

        assert!(parent.children().contains_key("child"));
        let child = parent.children().get("child").unwrap().first().unwrap();
        assert_eq!(child.value(), Some("Child"));
    };

    check_extensions(feed.extensions());
    check_extensions(entry.extensions());
}

#[test]
fn read_eof() {
    let result = Feed::read_from("".as_bytes());
    assert!(matches!(result, Err(Error::Eof)));
}

#[test]
fn read_invalid_start() {
    let result = Feed::read_from("<wrong></wrong>".as_bytes());
    assert!(matches!(result, Err(Error::InvalidStartTag)));
}

#[test]
fn read_invalid_attribute_lang() {
    let result = Feed::read_from("<feed xml:lang=\"&;\"></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn read_invalid_attribute_base() {
    let result = Feed::read_from("<feed xml:base=\"&;\"></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn read_invalid_attribute_namespace() {
    let result = Feed::read_from("<feed xmlns:invalid=\"&;\"></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn read_mismatched_tags() {
    let result = Feed::read_from("<feed></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn read_internal_invalid_tag() {
    let result = Feed::read_from("<feed><aba><aaa></aba></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn read_entry_internal_invalid_tag() {
    let result = Feed::read_from("<feed><entry><aaa></entry></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn link_invalid_attribute() {
    let result = Feed::read_from("<feed><link href=\"&;\"></link></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn text_invalid_xml_base() {
    let result = Feed::read_from("<feed><rights xml:base=\"&;\"></rights></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn text_invalid_xml_lang() {
    let result = Feed::read_from("<feed><rights xml:lang=\"&;\"></rights></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn text_invalid_type() {
    let result = Feed::read_from("<feed><rights type=\"&;\"></rights></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn author_internal_invalid_tag() {
    let result = Feed::read_from("<feed><author><invalid></author></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn source_internal_invalid_tag() {
    let result = Feed::read_from("<feed><entry><source><invalid></source></entry></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn content_invalid_xml_lang() {
    let result = Feed::read_from("<feed><entry><content xml:lang=\"&;\"></content></entry></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn content_invalid_xml_base() {
    let result = Feed::read_from("<feed><entry><content xml:base=\"&;\"></content></entry></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn content_invalid_type() {
    let result = Feed::read_from("<feed><entry><content type=\"&;\"></content></entry></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn content_invalid_src() {
    let result = Feed::read_from("<feed><entry><content src=\"&;\"></content></entry></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn category_invalid_term() {
    let result = Feed::read_from("<feed><category term=\"&;\"></category></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn category_invalid_scheme() {
    let result = Feed::read_from("<feed><category scheme=\"&;\"></category></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn category_invalid_label() {
    let result = Feed::read_from("<feed><category label=\"&;\"></category></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn generator_invalid_uri() {
    let result = Feed::read_from("<feed><generator uri=\"&;\"></generator></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}

#[test]
fn generator_invalid_version() {
    let result = Feed::read_from("<feed><generator version=\"&;\"></generator></feed>".as_bytes());
    assert!(matches!(result, Err(Error::Xml(_))));
}<|endoftext|>


<commit_before>extern crate futures;

use std::mem;
use std::sync::Arc;
use std::rc::Rc;
use std::cell::{Cell, RefCell};
use std::sync::atomic::{Ordering, AtomicBool};

use futures::prelude::*;
use futures::future::ok;
use futures::stream;
use futures::sync::{oneshot, mpsc};
use futures::task::{self, Task};
use futures::executor::{self, Notify};
use futures::sink::*;

mod support;
use support::*;

#[test]
fn vec_sink() {
    let mut v = Vec::new();
    assert_eq!(v.start_send(0), Ok(AsyncSink::Ready));
    assert_eq!(v.start_send(1), Ok(AsyncSink::Ready));
    assert_eq!(v, vec![0, 1]);
    assert_done(move || v.flush(), Ok(vec![0, 1]));
}

#[test]
fn send() {
    let v = Vec::new();

    let v = v.send(0).wait().unwrap();
    assert_eq!(v, vec![0]);

    let v = v.send(1).wait().unwrap();
    assert_eq!(v, vec![0, 1]);

    assert_done(move || v.send(2),
                Ok(vec![0, 1, 2]));
}

#[test]
fn send_all() {
    let v = Vec::new();

    let (v, _) = v.send_all(stream::iter_ok(vec![0, 1])).wait().unwrap();
    assert_eq!(v, vec![0, 1]);

    let (v, _) = v.send_all(stream::iter_ok(vec![2, 3])).wait().unwrap();
    assert_eq!(v, vec![0, 1, 2, 3]);

    assert_done(
        move || v.send_all(stream::iter_ok(vec![4, 5])).map(|(v, _)| v),
        Ok(vec![0, 1, 2, 3, 4, 5]));
}

// An Unpark struct that records unpark events for inspection
struct Flag(pub AtomicBool);

impl Flag {
    fn new() -> Arc<Flag> {
        Arc::new(Flag(AtomicBool::new(false)))
    }

    fn get(&self) -> bool {
        self.0.load(Ordering::SeqCst)
    }

    fn set(&self, v: bool) {
        self.0.store(v, Ordering::SeqCst)
    }
}

impl Notify for Flag {
    fn notify(&self, _id: usize) {
        self.set(true)
    }
}

// Sends a value on an i32 channel sink
struct StartSendFut<S: Sink>(Option<S>, Option<S::SinkItem>);

impl<S: Sink> StartSendFut<S> {
    fn new(sink: S, item: S::SinkItem) -> StartSendFut<S> {
        StartSendFut(Some(sink), Some(item))
    }
}

impl<S: Sink> Future for StartSendFut<S> {
    type Item = S;
    type Error = S::SinkError;

    fn poll(&mut self) -> Poll<S, S::SinkError> {
        match self.0.as_mut().unwrap().start_send(self.1.take().unwrap())? {
            AsyncSink::Ready => Ok(Async::Ready(self.0.take().unwrap())),
            AsyncSink::NotReady(item) => {
                self.1 = Some(item);
                Ok(Async::NotReady)
            }
        }

    }
}

#[test]
// Test that `start_send` on an `mpsc` channel does indeed block when the
// channel is full
fn mpsc_blocking_start_send() {
    let (mut tx, mut rx) = mpsc::channel::<i32>(0);

    futures::future::lazy(|| {
        assert_eq!(tx.start_send(0).unwrap(), AsyncSink::Ready);

        let flag = Flag::new();
        let mut task = executor::spawn(StartSendFut::new(tx, 1));

        assert!(task.poll_future_notify(&flag, 0).unwrap().is_not_ready());
        assert!(!flag.get());
        sassert_next(&mut rx, 0);
        assert!(flag.get());
        flag.set(false);
        assert!(task.poll_future_notify(&flag, 0).unwrap().is_ready());
        assert!(!flag.get());
        sassert_next(&mut rx, 1);

        Ok::<(), ()>(())
    }).wait().unwrap();
}

#[test]
// test `flush` by using `with` to make the first insertion into a sink block
// until a oneshot is completed
fn with_flush() {
    let (tx, rx) = oneshot::channel();
    let mut block = Box::new(rx) as Box<Future<Item = _, Error = _>>;
    let mut sink = Vec::new().with(|elem| {
        mem::replace(&mut block, Box::new(ok(())))
            .map(move |_| elem + 1).map_err(|_| -> () { panic!() })
    });

    assert_eq!(sink.start_send(0), Ok(AsyncSink::Ready));

    let flag = Flag::new();
    let mut task = executor::spawn(sink.flush());
    assert!(task.poll_future_notify(&flag, 0).unwrap().is_not_ready());
    tx.send(()).unwrap();
    assert!(flag.get());

    let sink = match task.poll_future_notify(&flag, 0).unwrap() {
        Async::Ready(sink) => sink,
        _ => panic!()
    };

    assert_eq!(sink.send(1).wait().unwrap().get_ref(), &[1, 2]);
}

#[test]
// test simple use of with to change data
fn with_as_map() {
    let sink = Vec::new().with(|item| -> Result<i32, ()> {
        Ok(item * 2)
    });
    let sink = sink.send(0).wait().unwrap();
    let sink = sink.send(1).wait().unwrap();
    let sink = sink.send(2).wait().unwrap();
    assert_eq!(sink.get_ref(), &[0, 2, 4]);
}

#[test]
// test simple use of with_flat_map
fn with_flat_map() {
    let sink = Vec::new().with_flat_map(|item| {
        stream::iter_ok(vec![item; item])
    });
    let sink = sink.send(0).wait().unwrap();
    let sink = sink.send(1).wait().unwrap();
    let sink = sink.send(2).wait().unwrap();
    let sink = sink.send(3).wait().unwrap();
    assert_eq!(sink.get_ref(), &[1,2,2,3,3,3]);
}

// Immediately accepts all requests to start pushing, but completion is managed
// by manually flushing
struct ManualFlush<T> {
    data: Vec<T>,
    waiting_tasks: Vec<Task>,
}

impl<T> Sink for ManualFlush<T> {
    type SinkItem = Option<T>; // Pass None to flush
    type SinkError = ();

    fn start_send(&mut self, op: Option<T>) -> StartSend<Option<T>, ()> {
        if let Some(item) = op {
            self.data.push(item);
        } else {
            self.force_flush();
        }
        Ok(AsyncSink::Ready)
    }

    fn poll_complete(&mut self) -> Poll<(), ()> {
        if self.data.is_empty() {
            Ok(Async::Ready(()))
        } else {
            self.waiting_tasks.push(task::current());
            Ok(Async::NotReady)
        }
    }

    fn close(&mut self) -> Poll<(), ()> {
        Ok(().into())
    }
}

impl<T> ManualFlush<T> {
    fn new() -> ManualFlush<T> {
        ManualFlush {
            data: Vec::new(),
            waiting_tasks: Vec::new()
        }
    }

    fn force_flush(&mut self) -> Vec<T> {
        for task in self.waiting_tasks.drain(..) {
            task.notify()
        }
        mem::replace(&mut self.data, Vec::new())
    }
}

#[test]
// test that the `with` sink doesn't require the underlying sink to flush,
// but doesn't claim to be flushed until the underlyig sink is
fn with_flush_propagate() {
    let mut sink = ManualFlush::new().with(|x| -> Result<Option<i32>, ()> { Ok(x) });
    assert_eq!(sink.start_send(Some(0)).unwrap(), AsyncSink::Ready);
    assert_eq!(sink.start_send(Some(1)).unwrap(), AsyncSink::Ready);

    let flag = Flag::new();
    let mut task = executor::spawn(sink.flush());
    assert!(task.poll_future_notify(&flag, 0).unwrap().is_not_ready());
    assert!(!flag.get());
    assert_eq!(task.get_mut().get_mut().get_mut().force_flush(), vec![0, 1]);
    assert!(flag.get());
    assert!(task.poll_future_notify(&flag, 0).unwrap().is_ready());
}

#[test]
// test that a buffer is a no-nop around a sink that always accepts sends
fn buffer_noop() {
    let sink = Vec::new().buffer(0);
    let sink = sink.send(0).wait().unwrap();
    let sink = sink.send(1).wait().unwrap();
    assert_eq!(sink.get_ref(), &[0, 1]);

    let sink = Vec::new().buffer(1);
    let sink = sink.send(0).wait().unwrap();
    let sink = sink.send(1).wait().unwrap();
    assert_eq!(sink.get_ref(), &[0, 1]);
}

struct ManualAllow<T> {
    data: Vec<T>,
    allow: Rc<Allow>,
}

struct Allow {
    flag: Cell<bool>,
    tasks: RefCell<Vec<Task>>,
}

impl Allow {
    fn new() -> Allow {
        Allow {
            flag: Cell::new(false),
            tasks: RefCell::new(Vec::new()),
        }
    }

    fn check(&self) -> bool {
        if self.flag.get() {
            true
        } else {
            self.tasks.borrow_mut().push(task::current());
            false
        }
    }

    fn start(&self) {
        self.flag.set(true);
        let mut tasks = self.tasks.borrow_mut();
        for task in tasks.drain(..) {
            task.notify();
        }
    }
}

impl<T> Sink for ManualAllow<T> {
    type SinkItem = T;
    type SinkError = ();

    fn start_send(&mut self, item: T) -> StartSend<T, ()> {
        if self.allow.check() {
            self.data.push(item);
            Ok(AsyncSink::Ready)
        } else {
            Ok(AsyncSink::NotReady(item))
        }
    }

    fn poll_complete(&mut self) -> Poll<(), ()> {
        Ok(Async::Ready(()))
    }

    fn close(&mut self) -> Poll<(), ()> {
        Ok(().into())
    }
}

fn manual_allow<T>() -> (ManualAllow<T>, Rc<Allow>) {
    let allow = Rc::new(Allow::new());
    let manual_allow = ManualAllow {
        data: Vec::new(),
        allow: allow.clone(),
    };
    (manual_allow, allow)
}

#[test]
// test basic buffer functionality, including both filling up to capacity,
// and writing out when the underlying sink is ready
fn buffer() {
    let (sink, allow) = manual_allow::<i32>();
    let sink = sink.buffer(2);

    let sink = StartSendFut::new(sink, 0).wait().unwrap();
    let sink = StartSendFut::new(sink, 1).wait().unwrap();

    let flag = Flag::new();
    let mut task = executor::spawn(sink.send(2));
    assert!(task.poll_future_notify(&flag, 0).unwrap().is_not_ready());
    assert!(!flag.get());
    allow.start();
    assert!(flag.get());
    match task.poll_future_notify(&flag, 0).unwrap() {
        Async::Ready(sink) => {
            assert_eq!(sink.get_ref().data, vec![0, 1, 2]);
        }
        _ => panic!()
    }
}

#[test]
fn map_err() {
    {
        let (tx, _rx) = mpsc::channel(1);
        let mut tx = tx.sink_map_err(|_| ());
        assert_eq!(tx.start_send(()), Ok(AsyncSink::Ready));
        assert_eq!(tx.poll_complete(), Ok(Async::Ready(())));
    }

    let tx = mpsc::channel(0).0;
    assert_eq!(tx.sink_map_err(|_| ()).start_send(()), Err(()));
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
struct FromErrTest;

impl<T> From<mpsc::SendError<T>> for FromErrTest {
    fn from(_: mpsc::SendError<T>) -> FromErrTest {
        FromErrTest
    }
}

#[test]
fn from_err() {
    {
        let (tx, _rx) = mpsc::channel(1);
        let mut tx: SinkFromErr<mpsc::Sender<()>, FromErrTest> = tx.sink_from_err();
        assert_eq!(tx.start_send(()), Ok(AsyncSink::Ready));
        assert_eq!(tx.poll_complete(), Ok(Async::Ready(())));
    }

    let tx = mpsc::channel(0).0;
    assert_eq!(tx.sink_from_err().start_send(()), Err(FromErrTest));
}
<commit_msg>Fix 1.13.0 build<commit_after>extern crate futures;

use std::mem;
use std::sync::Arc;
use std::rc::Rc;
use std::cell::{Cell, RefCell};
use std::sync::atomic::{Ordering, AtomicBool};

use futures::prelude::*;
use futures::future::ok;
use futures::stream;
use futures::sync::{oneshot, mpsc};
use futures::task::{self, Task};
use futures::executor::{self, Notify};
use futures::sink::SinkFromErr;

mod support;
use support::*;

#[test]
fn vec_sink() {
    let mut v = Vec::new();
    assert_eq!(v.start_send(0), Ok(AsyncSink::Ready));
    assert_eq!(v.start_send(1), Ok(AsyncSink::Ready));
    assert_eq!(v, vec![0, 1]);
    assert_done(move || v.flush(), Ok(vec![0, 1]));
}

#[test]
fn send() {
    let v = Vec::new();

    let v = v.send(0).wait().unwrap();
    assert_eq!(v, vec![0]);

    let v = v.send(1).wait().unwrap();
    assert_eq!(v, vec![0, 1]);

    assert_done(move || v.send(2),
                Ok(vec![0, 1, 2]));
}

#[test]
fn send_all() {
    let v = Vec::new();

    let (v, _) = v.send_all(stream::iter_ok(vec![0, 1])).wait().unwrap();
    assert_eq!(v, vec![0, 1]);

    let (v, _) = v.send_all(stream::iter_ok(vec![2, 3])).wait().unwrap();
    assert_eq!(v, vec![0, 1, 2, 3]);

    assert_done(
        move || v.send_all(stream::iter_ok(vec![4, 5])).map(|(v, _)| v),
        Ok(vec![0, 1, 2, 3, 4, 5]));
}

// An Unpark struct that records unpark events for inspection
struct Flag(pub AtomicBool);

impl Flag {
    fn new() -> Arc<Flag> {
        Arc::new(Flag(AtomicBool::new(false)))
    }

    fn get(&self) -> bool {
        self.0.load(Ordering::SeqCst)
    }

    fn set(&self, v: bool) {
        self.0.store(v, Ordering::SeqCst)
    }
}

impl Notify for Flag {
    fn notify(&self, _id: usize) {
        self.set(true)
    }
}

// Sends a value on an i32 channel sink
struct StartSendFut<S: Sink>(Option<S>, Option<S::SinkItem>);

impl<S: Sink> StartSendFut<S> {
    fn new(sink: S, item: S::SinkItem) -> StartSendFut<S> {
        StartSendFut(Some(sink), Some(item))
    }
}

impl<S: Sink> Future for StartSendFut<S> {
    type Item = S;
    type Error = S::SinkError;

    fn poll(&mut self) -> Poll<S, S::SinkError> {
        match self.0.as_mut().unwrap().start_send(self.1.take().unwrap())? {
            AsyncSink::Ready => Ok(Async::Ready(self.0.take().unwrap())),
            AsyncSink::NotReady(item) => {
                self.1 = Some(item);
                Ok(Async::NotReady)
            }
        }

    }
}

#[test]
// Test that `start_send` on an `mpsc` channel does indeed block when the
// channel is full
fn mpsc_blocking_start_send() {
    let (mut tx, mut rx) = mpsc::channel::<i32>(0);

    futures::future::lazy(|| {
        assert_eq!(tx.start_send(0).unwrap(), AsyncSink::Ready);

        let flag = Flag::new();
        let mut task = executor::spawn(StartSendFut::new(tx, 1));

        assert!(task.poll_future_notify(&flag, 0).unwrap().is_not_ready());
        assert!(!flag.get());
        sassert_next(&mut rx, 0);
        assert!(flag.get());
        flag.set(false);
        assert!(task.poll_future_notify(&flag, 0).unwrap().is_ready());
        assert!(!flag.get());
        sassert_next(&mut rx, 1);

        Ok::<(), ()>(())
    }).wait().unwrap();
}

#[test]
// test `flush` by using `with` to make the first insertion into a sink block
// until a oneshot is completed
fn with_flush() {
    let (tx, rx) = oneshot::channel();
    let mut block = Box::new(rx) as Box<Future<Item = _, Error = _>>;
    let mut sink = Vec::new().with(|elem| {
        mem::replace(&mut block, Box::new(ok(())))
            .map(move |_| elem + 1).map_err(|_| -> () { panic!() })
    });

    assert_eq!(sink.start_send(0), Ok(AsyncSink::Ready));

    let flag = Flag::new();
    let mut task = executor::spawn(sink.flush());
    assert!(task.poll_future_notify(&flag, 0).unwrap().is_not_ready());
    tx.send(()).unwrap();
    assert!(flag.get());

    let sink = match task.poll_future_notify(&flag, 0).unwrap() {
        Async::Ready(sink) => sink,
        _ => panic!()
    };

    assert_eq!(sink.send(1).wait().unwrap().get_ref(), &[1, 2]);
}

#[test]
// test simple use of with to change data
fn with_as_map() {
    let sink = Vec::new().with(|item| -> Result<i32, ()> {
        Ok(item * 2)
    });
    let sink = sink.send(0).wait().unwrap();
    let sink = sink.send(1).wait().unwrap();
    let sink = sink.send(2).wait().unwrap();
    assert_eq!(sink.get_ref(), &[0, 2, 4]);
}

#[test]
// test simple use of with_flat_map
fn with_flat_map() {
    let sink = Vec::new().with_flat_map(|item| {
        stream::iter_ok(vec![item; item])
    });
    let sink = sink.send(0).wait().unwrap();
    let sink = sink.send(1).wait().unwrap();
    let sink = sink.send(2).wait().unwrap();
    let sink = sink.send(3).wait().unwrap();
    assert_eq!(sink.get_ref(), &[1,2,2,3,3,3]);
}

// Immediately accepts all requests to start pushing, but completion is managed
// by manually flushing
struct ManualFlush<T> {
    data: Vec<T>,
    waiting_tasks: Vec<Task>,
}

impl<T> Sink for ManualFlush<T> {
    type SinkItem = Option<T>; // Pass None to flush
    type SinkError = ();

    fn start_send(&mut self, op: Option<T>) -> StartSend<Option<T>, ()> {
        if let Some(item) = op {
            self.data.push(item);
        } else {
            self.force_flush();
        }
        Ok(AsyncSink::Ready)
    }

    fn poll_complete(&mut self) -> Poll<(), ()> {
        if self.data.is_empty() {
            Ok(Async::Ready(()))
        } else {
            self.waiting_tasks.push(task::current());
            Ok(Async::NotReady)
        }
    }

    fn close(&mut self) -> Poll<(), ()> {
        Ok(().into())
    }
}

impl<T> ManualFlush<T> {
    fn new() -> ManualFlush<T> {
        ManualFlush {
            data: Vec::new(),
            waiting_tasks: Vec::new()
        }
    }

    fn force_flush(&mut self) -> Vec<T> {
        for task in self.waiting_tasks.drain(..) {
            task.notify()
        }
        mem::replace(&mut self.data, Vec::new())
    }
}

#[test]
// test that the `with` sink doesn't require the underlying sink to flush,
// but doesn't claim to be flushed until the underlyig sink is
fn with_flush_propagate() {
    let mut sink = ManualFlush::new().with(|x| -> Result<Option<i32>, ()> { Ok(x) });
    assert_eq!(sink.start_send(Some(0)).unwrap(), AsyncSink::Ready);
    assert_eq!(sink.start_send(Some(1)).unwrap(), AsyncSink::Ready);

    let flag = Flag::new();
    let mut task = executor::spawn(sink.flush());
    assert!(task.poll_future_notify(&flag, 0).unwrap().is_not_ready());
    assert!(!flag.get());
    assert_eq!(task.get_mut().get_mut().get_mut().force_flush(), vec![0, 1]);
    assert!(flag.get());
    assert!(task.poll_future_notify(&flag, 0).unwrap().is_ready());
}

#[test]
// test that a buffer is a no-nop around a sink that always accepts sends
fn buffer_noop() {
    let sink = Vec::new().buffer(0);
    let sink = sink.send(0).wait().unwrap();
    let sink = sink.send(1).wait().unwrap();
    assert_eq!(sink.get_ref(), &[0, 1]);

    let sink = Vec::new().buffer(1);
    let sink = sink.send(0).wait().unwrap();
    let sink = sink.send(1).wait().unwrap();
    assert_eq!(sink.get_ref(), &[0, 1]);
}

struct ManualAllow<T> {
    data: Vec<T>,
    allow: Rc<Allow>,
}

struct Allow {
    flag: Cell<bool>,
    tasks: RefCell<Vec<Task>>,
}

impl Allow {
    fn new() -> Allow {
        Allow {
            flag: Cell::new(false),
            tasks: RefCell::new(Vec::new()),
        }
    }

    fn check(&self) -> bool {
        if self.flag.get() {
            true
        } else {
            self.tasks.borrow_mut().push(task::current());
            false
        }
    }

    fn start(&self) {
        self.flag.set(true);
        let mut tasks = self.tasks.borrow_mut();
        for task in tasks.drain(..) {
            task.notify();
        }
    }
}

impl<T> Sink for ManualAllow<T> {
    type SinkItem = T;
    type SinkError = ();

    fn start_send(&mut self, item: T) -> StartSend<T, ()> {
        if self.allow.check() {
            self.data.push(item);
            Ok(AsyncSink::Ready)
        } else {
            Ok(AsyncSink::NotReady(item))
        }
    }

    fn poll_complete(&mut self) -> Poll<(), ()> {
        Ok(Async::Ready(()))
    }

    fn close(&mut self) -> Poll<(), ()> {
        Ok(().into())
    }
}

fn manual_allow<T>() -> (ManualAllow<T>, Rc<Allow>) {
    let allow = Rc::new(Allow::new());
    let manual_allow = ManualAllow {
        data: Vec::new(),
        allow: allow.clone(),
    };
    (manual_allow, allow)
}

#[test]
// test basic buffer functionality, including both filling up to capacity,
// and writing out when the underlying sink is ready
fn buffer() {
    let (sink, allow) = manual_allow::<i32>();
    let sink = sink.buffer(2);

    let sink = StartSendFut::new(sink, 0).wait().unwrap();
    let sink = StartSendFut::new(sink, 1).wait().unwrap();

    let flag = Flag::new();
    let mut task = executor::spawn(sink.send(2));
    assert!(task.poll_future_notify(&flag, 0).unwrap().is_not_ready());
    assert!(!flag.get());
    allow.start();
    assert!(flag.get());
    match task.poll_future_notify(&flag, 0).unwrap() {
        Async::Ready(sink) => {
            assert_eq!(sink.get_ref().data, vec![0, 1, 2]);
        }
        _ => panic!()
    }
}

#[test]
fn map_err() {
    {
        let (tx, _rx) = mpsc::channel(1);
        let mut tx = tx.sink_map_err(|_| ());
        assert_eq!(tx.start_send(()), Ok(AsyncSink::Ready));
        assert_eq!(tx.poll_complete(), Ok(Async::Ready(())));
    }

    let tx = mpsc::channel(0).0;
    assert_eq!(tx.sink_map_err(|_| ()).start_send(()), Err(()));
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
struct FromErrTest;

impl<T> From<mpsc::SendError<T>> for FromErrTest {
    fn from(_: mpsc::SendError<T>) -> FromErrTest {
        FromErrTest
    }
}

#[test]
fn from_err() {
    {
        let (tx, _rx) = mpsc::channel(1);
        let mut tx: SinkFromErr<mpsc::Sender<()>, FromErrTest> = tx.sink_from_err();
        assert_eq!(tx.start_send(()), Ok(AsyncSink::Ready));
        assert_eq!(tx.poll_complete(), Ok(Async::Ready(())));
    }

    let tx = mpsc::channel(0).0;
    assert_eq!(tx.sink_from_err().start_send(()), Err(FromErrTest));
}
<|endoftext|>


<commit_before>#[feature(globs)];
#[feature(macro_rules)];
#[feature(managed_boxes)];

#[link_args="-lwxc"];

extern mod native;
extern mod wx;

use std::libc::c_void;

use wx::_unsafe::*;
use wx::defs::*;
use wx::base::*;
use wx::core::*;

mod macros;

wxApp!(wx_main)

extern "C"
fn wx_main() {
    let frame = MyFrame::new();
    frame.show();
    frame.raise();
}

struct MyFrame(@wxFrame);
impl MyFrame {
    fn new() -> MyFrame {
        let frame = wxFrame::new(wxWindow::null(), wxID_ANY, "Hello, wxRust!", -1, -1, -1, -1, wxDEFAULT_FRAME_STYLE);
        let menubar = MyMenuBar::new();
        frame.setMenuBar(menubar.asMenuBar());

        MyButton::new(frame);

        MyFrame(frame)
    }
}

struct MyMenuBar(@wxMenuBar);
impl MyMenuBar {
    fn new() -> MyMenuBar {
        let menubar = wxMenuBar::new(0);

        let fileMenu = wxMenu::new("", 0);
        let fileNew = wxMenuItem::newEx(wxID_ANY, "New", "Create a new file.", 0, wxMenu::null());
        fileMenu.appendItem(fileNew);

        menubar.append(fileMenu, "File");
        MyMenuBar(menubar)
    }
    fn asMenuBar(&self) -> @wxMenuBar {
        return **self;
    }
}

struct MyButton(@wxButton);
impl MyButton {
    fn new<T: _wxWindow>(parent: &T) -> MyButton {
        let button = wxButton::new(parent, wxID_ANY, "Push me!", 10, 10, 50, 30, 0);
        let closure = wxClosure::new(MyButton::clicked as *mut c_void, parent.handle());
        unsafe {
            button.connect(wxID_ANY, wxID_ANY, expEVT_COMMAND_BUTTON_CLICKED(), closure.handle());
        }

        MyButton(button)
    }
    fn clicked(fun: *mut c_void, data: *mut c_void, evt: *mut c_void) {
        println("hello!");
        let parent = wxWindow::from(data);
        let msgDlg = wxMessageDialog::new(parent, "Pushed!!", "The Button", 0);
        msgDlg.showModal();
    }
}
<commit_msg>Convert button clicked event handler from member function to extern "C" free standing function to try to fix linux segfault(#21).<commit_after>#[feature(globs)];
#[feature(macro_rules)];
#[feature(managed_boxes)];

#[link_args="-lwxc"];

extern mod native;
extern mod wx;

use std::libc::c_void;

use wx::_unsafe::*;
use wx::defs::*;
use wx::base::*;
use wx::core::*;

mod macros;

wxApp!(wx_main)

extern "C"
fn wx_main() {
    let frame = MyFrame::new();
    frame.show();
    frame.raise();
}

struct MyFrame(@wxFrame);
impl MyFrame {
    fn new() -> MyFrame {
        let frame = wxFrame::new(wxWindow::null(), wxID_ANY, "Hello, wxRust!", -1, -1, -1, -1, wxDEFAULT_FRAME_STYLE);
        let menubar = MyMenuBar::new();
        frame.setMenuBar(menubar.asMenuBar());

        MyButton::new(frame);

        MyFrame(frame)
    }
}

struct MyMenuBar(@wxMenuBar);
impl MyMenuBar {
    fn new() -> MyMenuBar {
        let menubar = wxMenuBar::new(0);

        let fileMenu = wxMenu::new("", 0);
        let fileNew = wxMenuItem::newEx(wxID_ANY, "New", "Create a new file.", 0, wxMenu::null());
        fileMenu.appendItem(fileNew);

        menubar.append(fileMenu, "File");
        MyMenuBar(menubar)
    }
    fn asMenuBar(&self) -> @wxMenuBar {
        return **self;
    }
}

extern "C"
fn MyButton_clicked(fun: *mut c_void, data: *mut c_void, evt: *mut c_void) {
    println("hello!");
    let parent = wxWindow::from(data);
    let msgDlg = wxMessageDialog::new(parent, "Pushed!!", "The Button", 0);
    msgDlg.showModal();
}

struct MyButton(@wxButton);
impl MyButton {
    fn new<T: _wxWindow>(parent: &T) -> MyButton {
        let button = wxButton::new(parent, wxID_ANY, "Push me!", 10, 10, 50, 30, 0);
        let closure = wxClosure::new(MyButton_clicked as *mut c_void, parent.handle());
        unsafe {
            button.connect(wxID_ANY, wxID_ANY, expEVT_COMMAND_BUTTON_CLICKED(), closure.handle());
        }

        MyButton(button)
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate structure;

use std::os::raw::c_void;
use std::mem::transmute;
use std::io::ErrorKind;
use std::io::Cursor;

#[test]
fn pack() {
    assert_eq!(structure!("I").pack(3).unwrap(), vec![0, 0, 0, 3]);
}

#[test]
fn pack_into() {
    let mut v = Vec::new();
    structure!("I").pack_into(&mut v, 3).unwrap();
    assert_eq!(v, vec![0, 0, 0, 3]);
}

#[test]
fn unpack() {
    assert_eq!(structure!("I").unpack(&[0, 0, 0, 3]).unwrap(), (3, ));
}

#[test]
fn unpack_from() {
    assert_eq!(structure!("I").unpack_from(&mut Cursor::new(&[0, 0, 0, 3])).unwrap(), (3, ));
}

#[test]
fn pack_2_values() {
    assert_eq!(structure!("If").pack(6, 5.2).unwrap(), vec![0, 0, 0, 6, 64, 166, 102, 102]);
}

#[test]
fn unpack_2_values() {
    assert_eq!(structure!("If").unpack(&[0, 0, 0, 6, 64, 166, 102, 102]).unwrap(), (6, 5.2));
}

#[test]
fn pack_bool() {
    assert_eq!(structure!("?").pack(true).unwrap(), vec![1]);
    assert_eq!(structure!("?").pack(false).unwrap(), vec![0]);
}

#[test]
fn unpack_bool() {
    assert_eq!(structure!("?").unpack(&[1]).unwrap(), (true, ));
    assert_eq!(structure!("?").unpack(&[0]).unwrap(), (false, ));
}

#[test]
fn pack_big_endian() {
    assert_eq!(structure!("I").pack(1).unwrap(), vec![0, 0, 0, 1]);
    assert_eq!(structure!(">I").pack(1).unwrap(), vec![0, 0, 0, 1]);
    assert_eq!(structure!("!I").pack(1).unwrap(), vec![0, 0, 0, 1]);
}

#[test]
fn unpack_big_endian() {
    assert_eq!(structure!("I").unpack(&[0, 0, 0, 1]).unwrap(), (1, ));
    assert_eq!(structure!(">I").unpack(&[0, 0, 0, 1]).unwrap(), (1, ));
    assert_eq!(structure!("!I").unpack(&[0, 0, 0, 1]).unwrap(), (1, ));
}

#[test]
fn pack_little_endian() {
    assert_eq!(structure!("<I").pack(1).unwrap(), vec![1, 0, 0, 0]);
}

#[test]
fn unpack_little_endian() {
    assert_eq!(structure!("<I").unpack(&[1, 0, 0, 0]).unwrap(), (1, ));
}

#[test]
fn pack_native_endian() {
    let s = structure!("=I");
    if cfg!(target_endian = "little") {
        assert_eq!(s.pack(1).unwrap(), vec![1, 0, 0, 0]);
    } else {
        assert_eq!(s.pack(1).unwrap(), vec![0, 0, 0, 1]);
    }
}

#[test]
fn unpack_native_endian() {
    let s = structure!("=I");
    if cfg!(target_endian = "little") {
        assert_eq!(s.unpack(&[1, 0, 0, 0]).unwrap(), (1, ));
    } else {
        assert_eq!(s.unpack(&[0, 0, 0, 1]).unwrap(), (1, ));
    }
}

#[test]
fn pack_repeat_count() {
    assert_eq!(structure!("2B2?").pack(2, 3, true, false).unwrap(), vec![2, 3, 1, 0]);
}

#[test]
fn unpack_repeat_count() {
    assert_eq!(structure!("2B2?").unpack(&[2, 3, 1, 0]).unwrap(), (2, 3, true, false));
}

#[test]
fn pack_buffer() {
    assert_eq!(structure!("3s").pack(&[1, 2, 3]).unwrap(), vec![1, 2, 3]);
    assert_eq!(structure!("s").pack(&[4]).unwrap(), vec![4]);
    assert_eq!(structure!("0s").pack(&[]).unwrap(), vec![]);
    assert_eq!(structure!("2s").pack(&[5, 6, 7]).unwrap_err().kind(), ErrorKind::InvalidInput);
    assert_eq!(structure!("3s").pack(&[8, 9]).unwrap(), vec![8, 9, 0]);
}

#[test]
fn unpack_buffer() {
    assert_eq!(structure!("3s").unpack(&[1, 2, 3]).unwrap(), (vec![1, 2, 3], ));
    assert_eq!(structure!("s").unpack(&[4]).unwrap(), (vec![4], ));
    assert_eq!(structure!("0s").unpack(&[]).unwrap(), (vec![], ));
    assert_eq!(structure!("2s").unpack(&[5, 6, 7]).unwrap_err().kind(), ErrorKind::InvalidInput);
    assert_eq!(structure!("3s").unpack(&[8, 9]).unwrap_err().kind(), ErrorKind::InvalidInput);
}

#[test]
fn pack_fixed_buffer() {
    assert_eq!(structure!("3S").pack(&[1, 2, 3]).unwrap(), vec![1, 2, 3]);
    assert_eq!(structure!("S").pack(&[4]).unwrap(), vec![4]);
    assert_eq!(structure!("0S").pack(&[]).unwrap(), vec![]);
    assert_eq!(structure!("2S").pack(&[5, 6, 7]).unwrap_err().kind(), ErrorKind::InvalidInput);
    assert_eq!(structure!("3S").pack(&[8, 9]).unwrap_err().kind(), ErrorKind::InvalidInput);
}

#[test]
fn unpack_fixed_buffer() {
    assert_eq!(structure!("3S").unpack(&[1, 2, 3]).unwrap(), (vec![1, 2, 3], ));
    assert_eq!(structure!("S").unpack(&[4]).unwrap(), (vec![4], ));
    assert_eq!(structure!("0S").unpack(&[]).unwrap(), (vec![], ));
    assert_eq!(structure!("2S").unpack(&[5, 6, 7]).unwrap_err().kind(), ErrorKind::InvalidInput);
    assert_eq!(structure!("3S").unpack(&[8, 9]).unwrap_err().kind(), ErrorKind::InvalidInput);
}

#[test]
fn pack_and_unpack_pointer() {
    let num: u32 = 6;
    let num2: u32 = 7;
    assert_eq!(structure!("=P").pack(unsafe { transmute::<&u32, *const c_void>(&num) }).unwrap(), unsafe { transmute::<&u32, [u8; 8]>(&num) });
    let packed_pointers = structure!("=PP").pack(unsafe { transmute::<&u32, *const c_void>(&num) }, unsafe { transmute::<&u32, *const c_void>(&num2) }).unwrap();
    let (p, p2) = structure!("=PP").unpack(packed_pointers).unwrap();
    assert_eq!(p, unsafe { transmute::<&u32, *const c_void>(&num) });
    assert_eq!(p2, unsafe { transmute::<&u32, *const c_void>(&num2) });
}

#[test]
fn pack_and_unpack_typed_pointer() {
    let num: u32 = 6;
    let num2: u8 = 7;
    let num3: u8 = 8;
    let s = structure!("=P<u32>2P<u8>");
    let packed_pointers = s.pack(&num as *const u32, &num2 as *const u8, &num3 as *const u8).unwrap();
    let (p, p2, p3) = s.unpack(packed_pointers).unwrap();
    assert_eq!(p, &num as *const u32);
    assert_eq!(p2, &num2 as *const u8);
    assert_eq!(p3, &num3 as *const u8);
}
<commit_msg>Transmute pointer to 4 bytes buffer on 32 bit machines<commit_after>#[macro_use]
extern crate structure;

use std::os::raw::c_void;
use std::mem::transmute;
use std::io::ErrorKind;
use std::io::Cursor;

#[test]
fn pack() {
    assert_eq!(structure!("I").pack(3).unwrap(), vec![0, 0, 0, 3]);
}

#[test]
fn pack_into() {
    let mut v = Vec::new();
    structure!("I").pack_into(&mut v, 3).unwrap();
    assert_eq!(v, vec![0, 0, 0, 3]);
}

#[test]
fn unpack() {
    assert_eq!(structure!("I").unpack(&[0, 0, 0, 3]).unwrap(), (3, ));
}

#[test]
fn unpack_from() {
    assert_eq!(structure!("I").unpack_from(&mut Cursor::new(&[0, 0, 0, 3])).unwrap(), (3, ));
}

#[test]
fn pack_2_values() {
    assert_eq!(structure!("If").pack(6, 5.2).unwrap(), vec![0, 0, 0, 6, 64, 166, 102, 102]);
}

#[test]
fn unpack_2_values() {
    assert_eq!(structure!("If").unpack(&[0, 0, 0, 6, 64, 166, 102, 102]).unwrap(), (6, 5.2));
}

#[test]
fn pack_bool() {
    assert_eq!(structure!("?").pack(true).unwrap(), vec![1]);
    assert_eq!(structure!("?").pack(false).unwrap(), vec![0]);
}

#[test]
fn unpack_bool() {
    assert_eq!(structure!("?").unpack(&[1]).unwrap(), (true, ));
    assert_eq!(structure!("?").unpack(&[0]).unwrap(), (false, ));
}

#[test]
fn pack_big_endian() {
    assert_eq!(structure!("I").pack(1).unwrap(), vec![0, 0, 0, 1]);
    assert_eq!(structure!(">I").pack(1).unwrap(), vec![0, 0, 0, 1]);
    assert_eq!(structure!("!I").pack(1).unwrap(), vec![0, 0, 0, 1]);
}

#[test]
fn unpack_big_endian() {
    assert_eq!(structure!("I").unpack(&[0, 0, 0, 1]).unwrap(), (1, ));
    assert_eq!(structure!(">I").unpack(&[0, 0, 0, 1]).unwrap(), (1, ));
    assert_eq!(structure!("!I").unpack(&[0, 0, 0, 1]).unwrap(), (1, ));
}

#[test]
fn pack_little_endian() {
    assert_eq!(structure!("<I").pack(1).unwrap(), vec![1, 0, 0, 0]);
}

#[test]
fn unpack_little_endian() {
    assert_eq!(structure!("<I").unpack(&[1, 0, 0, 0]).unwrap(), (1, ));
}

#[test]
fn pack_native_endian() {
    let s = structure!("=I");
    if cfg!(target_endian = "little") {
        assert_eq!(s.pack(1).unwrap(), vec![1, 0, 0, 0]);
    } else {
        assert_eq!(s.pack(1).unwrap(), vec![0, 0, 0, 1]);
    }
}

#[test]
fn unpack_native_endian() {
    let s = structure!("=I");
    if cfg!(target_endian = "little") {
        assert_eq!(s.unpack(&[1, 0, 0, 0]).unwrap(), (1, ));
    } else {
        assert_eq!(s.unpack(&[0, 0, 0, 1]).unwrap(), (1, ));
    }
}

#[test]
fn pack_repeat_count() {
    assert_eq!(structure!("2B2?").pack(2, 3, true, false).unwrap(), vec![2, 3, 1, 0]);
}

#[test]
fn unpack_repeat_count() {
    assert_eq!(structure!("2B2?").unpack(&[2, 3, 1, 0]).unwrap(), (2, 3, true, false));
}

#[test]
fn pack_buffer() {
    assert_eq!(structure!("3s").pack(&[1, 2, 3]).unwrap(), vec![1, 2, 3]);
    assert_eq!(structure!("s").pack(&[4]).unwrap(), vec![4]);
    assert_eq!(structure!("0s").pack(&[]).unwrap(), vec![]);
    assert_eq!(structure!("2s").pack(&[5, 6, 7]).unwrap_err().kind(), ErrorKind::InvalidInput);
    assert_eq!(structure!("3s").pack(&[8, 9]).unwrap(), vec![8, 9, 0]);
}

#[test]
fn unpack_buffer() {
    assert_eq!(structure!("3s").unpack(&[1, 2, 3]).unwrap(), (vec![1, 2, 3], ));
    assert_eq!(structure!("s").unpack(&[4]).unwrap(), (vec![4], ));
    assert_eq!(structure!("0s").unpack(&[]).unwrap(), (vec![], ));
    assert_eq!(structure!("2s").unpack(&[5, 6, 7]).unwrap_err().kind(), ErrorKind::InvalidInput);
    assert_eq!(structure!("3s").unpack(&[8, 9]).unwrap_err().kind(), ErrorKind::InvalidInput);
}

#[test]
fn pack_fixed_buffer() {
    assert_eq!(structure!("3S").pack(&[1, 2, 3]).unwrap(), vec![1, 2, 3]);
    assert_eq!(structure!("S").pack(&[4]).unwrap(), vec![4]);
    assert_eq!(structure!("0S").pack(&[]).unwrap(), vec![]);
    assert_eq!(structure!("2S").pack(&[5, 6, 7]).unwrap_err().kind(), ErrorKind::InvalidInput);
    assert_eq!(structure!("3S").pack(&[8, 9]).unwrap_err().kind(), ErrorKind::InvalidInput);
}

#[test]
fn unpack_fixed_buffer() {
    assert_eq!(structure!("3S").unpack(&[1, 2, 3]).unwrap(), (vec![1, 2, 3], ));
    assert_eq!(structure!("S").unpack(&[4]).unwrap(), (vec![4], ));
    assert_eq!(structure!("0S").unpack(&[]).unwrap(), (vec![], ));
    assert_eq!(structure!("2S").unpack(&[5, 6, 7]).unwrap_err().kind(), ErrorKind::InvalidInput);
    assert_eq!(structure!("3S").unpack(&[8, 9]).unwrap_err().kind(), ErrorKind::InvalidInput);
}

#[test]
fn pack_and_unpack_pointer() {
    let num: u32 = 6;
    let num2: u32 = 7;
    #[cfg(target_pointer_width = "64")]
    {
        assert_eq!(structure!("=P").pack(unsafe { transmute::<&u32, *const c_void>(&num) }).unwrap(), unsafe { transmute::<&u32, [u8; 8]>(&num) });
    }
    #[cfg(target_pointer_width = "32")]
    {
        assert_eq!(structure!("=P").pack(unsafe { transmute::<&u32, *const c_void>(&num) }).unwrap(), unsafe { transmute::<&u32, [u8; 4]>(&num) });
    }
    let packed_pointers = structure!("=PP").pack(unsafe { transmute::<&u32, *const c_void>(&num) }, unsafe { transmute::<&u32, *const c_void>(&num2) }).unwrap();
    let (p, p2) = structure!("=PP").unpack(packed_pointers).unwrap();
    assert_eq!(p, unsafe { transmute::<&u32, *const c_void>(&num) });
    assert_eq!(p2, unsafe { transmute::<&u32, *const c_void>(&num2) });
}

#[test]
fn pack_and_unpack_typed_pointer() {
    let num: u32 = 6;
    let num2: u8 = 7;
    let num3: u8 = 8;
    let s = structure!("=P<u32>2P<u8>");
    let packed_pointers = s.pack(&num as *const u32, &num2 as *const u8, &num3 as *const u8).unwrap();
    let (p, p2, p3) = s.unpack(packed_pointers).unwrap();
    assert_eq!(p, &num as *const u32);
    assert_eq!(p2, &num2 as *const u8);
    assert_eq!(p3, &num3 as *const u8);
}
<|endoftext|>


<commit_before>extern crate easystring;

#[cfg(test)]
mod length {
    use easystring::Text;

    #[test]
    fn zero() {
        assert_eq!(Text::new().len(), 0);
    }

    #[test]
    fn non_zero() {
        let text = Text::from("1234567890");
        assert_eq!(text.len(), 10);
    }

    #[test]
    fn empty() {
        assert!(Text::new().is_empty());
    }

    #[test]
    fn not_empty() {
        let text = Text::from("1234567890");
        assert!(!text.is_empty());
    }
}

#[cfg(test)]
mod from {
    use std::path::{Path, PathBuf};
    use easystring::Text;

    const STRING: &'static str = "EaSyStRiNg";
    #[test]
    fn str() {
        let text = Text::from(STRING);
        assert_eq!(&text, STRING);
    }

    #[test]
    fn string() {
        let string = String::from(STRING);
        let text = Text::from(string);
        assert_eq!(&text, STRING);
    }

    #[test]
    fn path() {
        let path = Path::new(STRING);
        let text = Text::from(path);
        assert_eq!(&text, STRING)
    }

    #[test]
    fn pathbuf() {
        let path = PathBuf::from(STRING);
        let text = Text::from(path);
        assert_eq!(&text, STRING)
    }
}

#[cfg(test)]
mod partial_equality_direct {
    use std::path::{Path, PathBuf};
    use easystring::Text;

    const STRING: &'static str = "EaSyStRiNg";

    #[test]
    fn str() {
        let text = Text::from(STRING);
        assert_eq!(text, STRING);
    }

    #[test]
    fn string() {
        let text = Text::from(STRING);
        let string = String::from(STRING);
        assert_eq!(text, string);
    }

    #[test]
    fn path() {
        let path = Path::new(STRING);
        let text = Text::from(STRING);
        assert_eq!(text, path);
    }

    #[test]
    fn pathbuf() {
        let pathbuf = PathBuf::from(STRING);
        let text = Text::from(STRING);
        assert_eq!(text, pathbuf);
    }
}

#[cfg(test)]
mod partial_equality_as_ref {
    use std::path::{Path, PathBuf};
    use easystring::Text;

    const STRING: &'static str = "EaSyStRiNg";

    #[test]
    fn str() {
        let text = Text::from(STRING);
        assert_eq!(&text, STRING);
    }

    #[test]
    fn string() {
        let text = Text::from(STRING);
        let string = String::from(STRING);
        assert_eq!(&text, string);
    }

    #[test]
    fn path() {
        let path = Path::new(STRING);
        let text = Text::from(STRING);
        assert_eq!(&text, path);
    }

    #[test]
    fn pathbuf() {
        let pathbuf = PathBuf::from(STRING);
        let text = Text::from(STRING);
        assert_eq!(&text, pathbuf);
    }
}

#[cfg(test)]
mod ops {
    use std::path::{Path, PathBuf};
    use easystring::Text;

    #[test]
    fn add_text() {
        let t1 = Text::from("123");
        let t2 = Text::from("456");
        let text = t1 + t2;
        assert_eq!(text, "123456");
    }

    #[test]
    fn add_string() {
        let t1 = Text::from("123");
        let t2 = String::from("456");
        let text = t1 + t2;
        assert_eq!(text, "123456");
    }

    #[test]
    fn add_path() {
        let t1 = Text::from("123");
        let t2 = Path::new("456");
        let text = t1 + t2;
        assert_eq!(text, "123456");
    }

    #[test]
    fn add_pathbuf() {
        let t1 = Text::from("123");
        let t2 = PathBuf::from("456");
        let text = t1 + t2;
        assert_eq!(text, "123456");
    }

    #[test]
    fn add_multi() {
        let t0 = Text::new();
        let t1 = String::from("123");
        let t2 = Path::new("456");
        let t3 = PathBuf::from("789");
        let text: Text = t0 + t1 + t2 + t3;
        assert_eq!(text, "123456789");
    }
}

#[cfg(test)]
mod from_text {
    use std::path::{Path, PathBuf};
    use easystring::Text;

    #[test]
    fn string() {
        let t1 = String::from(Text::from("123"));
        let t2 = String::from("123");
        assert_eq!(t1, t2);
    }

    #[test]
    fn path() {
        let text = Text::from("123");
        let t1: &Path = (&text).into();
        let t2 = Path::new("123");
        assert_eq!(t1, t2);
    }
}
<commit_msg>Refactor tests<commit_after>extern crate easystring;

#[cfg(test)]
mod text {

    mod length {
        use easystring::Text;

        #[test]
        fn zero() {
            assert_eq!(Text::new().len(), 0);
        }

        #[test]
        fn non_zero() {
            let text = Text::from("1234567890");
            assert_eq!(text.len(), 10);
        }

        #[test]
        fn empty() {
            assert!(Text::new().is_empty());
        }

        #[test]
        fn not_empty() {
            let text = Text::from("1234567890");
            assert!(!text.is_empty());
        }
    }

    #[cfg(test)]
    mod from {
        use std::path::{Path, PathBuf};
        use easystring::Text;

        const STRING: &'static str = "EaSyStRiNg";
        #[test]
        fn str() {
            let text = Text::from(STRING);
            assert_eq!(&text, STRING);
        }

        #[test]
        fn string() {
            let string = String::from(STRING);
            let text = Text::from(string);
            assert_eq!(&text, STRING);
        }

        #[test]
        fn path() {
            let path = Path::new(STRING);
            let text = Text::from(path);
            assert_eq!(&text, STRING)
        }

        #[test]
        fn pathbuf() {
            let path = PathBuf::from(STRING);
            let text = Text::from(path);
            assert_eq!(&text, STRING)
        }
    }

    #[cfg(test)]
    mod partial_equality_direct {
        use std::path::{Path, PathBuf};
        use easystring::Text;

        const STRING: &'static str = "EaSyStRiNg";

        #[test]
        fn str() {
            let text = Text::from(STRING);
            assert_eq!(text, STRING);
        }

        #[test]
        fn string() {
            let text = Text::from(STRING);
            let string = String::from(STRING);
            assert_eq!(text, string);
        }

        #[test]
        fn path() {
            let path = Path::new(STRING);
            let text = Text::from(STRING);
            assert_eq!(text, path);
        }

        #[test]
        fn pathbuf() {
            let pathbuf = PathBuf::from(STRING);
            let text = Text::from(STRING);
            assert_eq!(text, pathbuf);
        }
    }

    #[cfg(test)]
    mod partial_equality_as_ref {
        use std::path::{Path, PathBuf};
        use easystring::Text;

        const STRING: &'static str = "EaSyStRiNg";

        #[test]
        fn str() {
            let text = Text::from(STRING);
            assert_eq!(&text, STRING);
        }

        #[test]
        fn string() {
            let text = Text::from(STRING);
            let string = String::from(STRING);
            assert_eq!(&text, string);
        }

        #[test]
        fn path() {
            let path = Path::new(STRING);
            let text = Text::from(STRING);
            assert_eq!(&text, path);
        }

        #[test]
        fn pathbuf() {
            let pathbuf = PathBuf::from(STRING);
            let text = Text::from(STRING);
            assert_eq!(&text, pathbuf);
        }
    }

    #[cfg(test)]
    mod ops {
        use std::path::{Path, PathBuf};
        use easystring::Text;

        #[test]
        fn add_text() {
            let t1 = Text::from("123");
            let t2 = Text::from("456");
            let text = t1 + t2;
            assert_eq!(text, "123456");
        }

        #[test]
        fn add_string() {
            let t1 = Text::from("123");
            let t2 = String::from("456");
            let text = t1 + t2;
            assert_eq!(text, "123456");
        }

        #[test]
        fn add_path() {
            let t1 = Text::from("123");
            let t2 = Path::new("456");
            let text = t1 + t2;
            assert_eq!(text, "123456");
        }

        #[test]
        fn add_pathbuf() {
            let t1 = Text::from("123");
            let t2 = PathBuf::from("456");
            let text = t1 + t2;
            assert_eq!(text, "123456");
        }

        #[test]
        fn add_multi() {
            let t0 = Text::new();
            let t1 = String::from("123");
            let t2 = Path::new("456");
            let t3 = PathBuf::from("789");
            let text: Text = t0 + t1 + t2 + t3;
            assert_eq!(text, "123456789");
        }
    }

    #[cfg(test)]
    mod from_text {
        use std::path::{Path, PathBuf};
        use easystring::Text;

        #[test]
        fn string() {
            let t1 = String::from(Text::from("123"));
            let t2 = String::from("123");
            assert_eq!(t1, t2);
        }

        #[test]
        fn path() {
            let text = Text::from("123");
            let t1: &Path = (&text).into();
            let t2 = Path::new("123");
            assert_eq!(t1, t2);
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
pub extern crate crossbeam_channel as channel;

extern crate crossbeam;
extern crate rand;

mod wrappers;

macro_rules! tests {
    ($channel:path) => {
        use std::sync::atomic::AtomicUsize;
        use std::sync::atomic::Ordering;
        use std::thread;
        use std::time::Duration;

        use $channel as channel;
        use crossbeam;
        use rand::{thread_rng, Rng};

        fn ms(ms: u64) -> Duration {
            Duration::from_millis(ms)
        }

        #[test]
        fn smoke() {
            let (s, r) = channel::bounded(0);
            select! {
                send(s, 7) => panic!(),
                default => {}
            }
            assert_eq!(r.try_recv(), None);

            assert_eq!(s.capacity(), Some(0));
            assert_eq!(r.capacity(), Some(0));
        }

        #[test]
        fn capacity() {
            let (s, r) = channel::bounded::<()>(0);
            assert_eq!(s.capacity(), Some(0));
            assert_eq!(r.capacity(), Some(0));
        }

        #[test]
        fn len_empty_full() {
            let (s, r) = channel::bounded(0);

            assert_eq!(s.len(), 0);
            assert_eq!(s.is_empty(), true);
            assert_eq!(s.is_full(), true);
            assert_eq!(r.len(), 0);
            assert_eq!(r.is_empty(), true);
            assert_eq!(r.is_full(), true);

            crossbeam::scope(|scope| {
                scope.spawn(|| s.send(0));
                scope.spawn(|| r.recv().unwrap());
            });

            assert_eq!(s.len(), 0);
            assert_eq!(s.is_empty(), true);
            assert_eq!(s.is_full(), true);
            assert_eq!(r.len(), 0);
            assert_eq!(r.is_empty(), true);
            assert_eq!(r.is_full(), true);
        }

        #[test]
        fn recv() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    assert_eq!(r.recv(), Some(7));
                    thread::sleep(ms(1000));
                    assert_eq!(r.recv(), Some(8));
                    thread::sleep(ms(1000));
                    assert_eq!(r.recv(), Some(9));
                    assert_eq!(r.recv(), None);
                });
                scope.spawn(move || {
                    thread::sleep(ms(1500));
                    s.send(7);
                    s.send(8);
                    s.send(9);
                });
            });
        }

        #[test]
        fn recv_timeout() {
            let (s, r) = channel::bounded::<i32>(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    select! {
                        recv(r) => panic!(),
                        recv(channel::after(ms(1000))) => {}
                    }
                    select! {
                        recv(r, v) => assert_eq!(v, Some(7)),
                        recv(channel::after(ms(1000))) => panic!(),
                    }
                    select! {
                        recv(r, v) => assert_eq!(v, None),
                        recv(channel::after(ms(1000))) => panic!(),
                    }
                });
                scope.spawn(move || {
                    thread::sleep(ms(1500));
                    s.send(7);
                });
            });
        }

        #[test]
        fn try_recv() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    assert_eq!(r.try_recv(), None);
                    thread::sleep(ms(1500));
                    assert_eq!(r.try_recv(), Some(7));
                    thread::sleep(ms(500));
                    assert_eq!(r.try_recv(), None);
                });
                scope.spawn(move || {
                    thread::sleep(ms(1000));
                    s.send(7);
                });
            });
        }

        #[test]
        fn send() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    s.send(7);
                    thread::sleep(ms(1000));
                    s.send(8);
                    thread::sleep(ms(1000));
                    s.send(9);
                });
                scope.spawn(move || {
                    thread::sleep(ms(1500));
                    assert_eq!(r.recv(), Some(7));
                    assert_eq!(r.recv(), Some(8));
                    assert_eq!(r.recv(), Some(9));
                });
            });
        }

        #[test]
        fn send_timeout() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    select! {
                        send(s, 7) => panic!(),
                        recv(channel::after(ms(1000))) => {}
                    }
                    select! {
                        send(s, 8) => {}
                        recv(channel::after(ms(1000))) => panic!(),
                    }
                    select! {
                        send(s, 9) => panic!(),
                        recv(channel::after(ms(1000))) => {}
                    }
                });
                scope.spawn(move || {
                    thread::sleep(ms(1500));
                    assert_eq!(r.recv(), Some(8));
                });
            });
        }

        #[test]
        fn try_send() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    select! {
                        send(s, 7) => panic!(),
                        default => {}
                    }
                    thread::sleep(ms(1500));
                    select! {
                        send(s, 8) => {}
                        default => panic!(),
                    }
                    thread::sleep(ms(500));
                    select! {
                        send(s, 9) => panic!(),
                        default => {}
                    }
                });
                scope.spawn(move || {
                    thread::sleep(ms(1000));
                    assert_eq!(r.recv(), Some(8));
                });
            });
        }

        #[test]
        fn len() {
            const COUNT: usize = 25_000;

            let (s, r) = channel::bounded(0);

            assert_eq!(s.len(), 0);
            assert_eq!(r.len(), 0);

            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    for i in 0..COUNT {
                        assert_eq!(r.recv(), Some(i));
                        assert_eq!(r.len(), 0);
                    }
                });

                scope.spawn(|| {
                    for i in 0..COUNT {
                        s.send(i);
                        assert_eq!(s.len(), 0);
                    }
                });
            });

            assert_eq!(s.len(), 0);
            assert_eq!(r.len(), 0);
        }

        #[test]
        fn close_signals_receiver() {
            let (s, r) = channel::bounded::<()>(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    assert_eq!(r.recv(), None);
                });
                scope.spawn(move || {
                    thread::sleep(ms(1000));
                    drop(s);
                });
            });
        }

        #[test]
        fn spsc() {
            const COUNT: usize = 100_000;

            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    for i in 0..COUNT {
                        assert_eq!(r.recv(), Some(i));
                    }
                    assert_eq!(r.recv(), None);
                });
                scope.spawn(move || {
                    for i in 0..COUNT {
                        s.send(i);
                    }
                });
            });
        }

        #[test]
        fn mpmc() {
            const COUNT: usize = 25_000;
            const THREADS: usize = 4;

            let (s, r) = channel::bounded::<usize>(0);
            let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>();

            crossbeam::scope(|scope| {
                for _ in 0..THREADS {
                    scope.spawn(|| {
                        for _ in 0..COUNT {
                            let n = r.recv().unwrap();
                            v[n].fetch_add(1, Ordering::SeqCst);
                        }
                    });
                }
                for _ in 0..THREADS {
                    scope.spawn(|| {
                        for i in 0..COUNT {
                            s.send(i);
                        }
                    });
                }
            });

            for c in v {
                assert_eq!(c.load(Ordering::SeqCst), THREADS);
            }
        }

        #[test]
        fn stress_timeout_two_threads() {
            const COUNT: usize = 100;

            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    for i in 0..COUNT {
                        if i % 2 == 0 {
                            thread::sleep(ms(50));
                        }
                        loop {
                            select! {
                                send(s, i) => break,
                                recv(channel::after(ms(10))) => {}
                            }
                        }
                    }
                });

                scope.spawn(|| {
                    for i in 0..COUNT {
                        if i % 2 == 0 {
                            thread::sleep(ms(50));
                        }
                        loop {
                            select! {
                                recv(r, v) => {
                                    assert_eq!(v, Some(i));
                                    break;
                                }
                                recv(channel::after(ms(10))) => {}
                            }
                        }
                    }
                });
            });
        }

        #[test]
        fn drops() {
            static DROPS: AtomicUsize = AtomicUsize::new(0);

            #[derive(Debug, PartialEq)]
            struct DropCounter;

            impl Drop for DropCounter {
                fn drop(&mut self) {
                    DROPS.fetch_add(1, Ordering::SeqCst);
                }
            }

            let mut rng = thread_rng();

            for _ in 0..100 {
                let steps = rng.gen_range(0, 3_000);

                DROPS.store(0, Ordering::SeqCst);
                let (s, r) = channel::bounded::<DropCounter>(0);

                crossbeam::scope(|scope| {
                    scope.spawn(|| {
                        for _ in 0..steps {
                            r.recv().unwrap();
                        }
                    });

                    scope.spawn(|| {
                        for _ in 0..steps {
                            s.send(DropCounter);
                        }
                    });
                });

                assert_eq!(DROPS.load(Ordering::SeqCst), steps);
                drop(s);
                drop(r);
                assert_eq!(DROPS.load(Ordering::SeqCst), steps);
            }
        }

        #[test]
        fn fairness() {
            const COUNT: usize = 10_000;

            let (s1, r1) = channel::bounded::<()>(0);
            let (s2, r2) = channel::bounded::<()>(0);

            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let mut hits = [0usize; 2];
                    for _ in 0..COUNT {
                        select! {
                            recv(r1) => hits[0] += 1,
                            recv(r2) => hits[1] += 1,
                        }
                    }
                    assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
                });

                let mut hits = [0usize; 2];
                for _ in 0..COUNT {
                    select! {
                        send(s1, ()) => hits[0] += 1,
                        send(s2, ()) => hits[1] += 1,
                    }
                }
                assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
            });
        }

        #[test]
        fn fairness_duplicates() {
            const COUNT: usize = 10_000;

            let (s, r) = channel::bounded::<()>(0);

            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let mut hits = [0usize; 5];
                    for _ in 0..COUNT {
                        select! {
                            recv(r) => hits[0] += 1,
                            recv(r) => hits[1] += 1,
                            recv(r) => hits[2] += 1,
                            recv(r) => hits[3] += 1,
                            recv(r) => hits[4] += 1,
                        }
                    }
                    assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
                });

                let mut hits = [0usize; 5];
                for _ in 0..COUNT {
                    select! {
                        send(s, ()) => hits[0] += 1,
                        send(s, ()) => hits[1] += 1,
                        send(s, ()) => hits[2] += 1,
                        send(s, ()) => hits[3] += 1,
                        send(s, ()) => hits[4] += 1,
                    }
                }
                assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
            });
        }

        #[test]
        fn recv_in_send() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    thread::sleep(ms(100));
                    r.recv()
                });

                scope.spawn(|| {
                    thread::sleep(ms(500));
                    s.send(());
                });

                select! {
                    send(s, r.recv().unwrap()) => {}
                }
            });
        }
    };
}

mod normal {
    tests!(wrappers::normal);
}

mod select {
    tests!(wrappers::select);
}

mod select_spin {
    tests!(wrappers::select_spin);
}

mod selet_multi {
    tests!(wrappers::select_multi);
}
<commit_msg>Fix a typo<commit_after>#[macro_use]
pub extern crate crossbeam_channel as channel;

extern crate crossbeam;
extern crate rand;

mod wrappers;

macro_rules! tests {
    ($channel:path) => {
        use std::sync::atomic::AtomicUsize;
        use std::sync::atomic::Ordering;
        use std::thread;
        use std::time::Duration;

        use $channel as channel;
        use crossbeam;
        use rand::{thread_rng, Rng};

        fn ms(ms: u64) -> Duration {
            Duration::from_millis(ms)
        }

        #[test]
        fn smoke() {
            let (s, r) = channel::bounded(0);
            select! {
                send(s, 7) => panic!(),
                default => {}
            }
            assert_eq!(r.try_recv(), None);

            assert_eq!(s.capacity(), Some(0));
            assert_eq!(r.capacity(), Some(0));
        }

        #[test]
        fn capacity() {
            let (s, r) = channel::bounded::<()>(0);
            assert_eq!(s.capacity(), Some(0));
            assert_eq!(r.capacity(), Some(0));
        }

        #[test]
        fn len_empty_full() {
            let (s, r) = channel::bounded(0);

            assert_eq!(s.len(), 0);
            assert_eq!(s.is_empty(), true);
            assert_eq!(s.is_full(), true);
            assert_eq!(r.len(), 0);
            assert_eq!(r.is_empty(), true);
            assert_eq!(r.is_full(), true);

            crossbeam::scope(|scope| {
                scope.spawn(|| s.send(0));
                scope.spawn(|| r.recv().unwrap());
            });

            assert_eq!(s.len(), 0);
            assert_eq!(s.is_empty(), true);
            assert_eq!(s.is_full(), true);
            assert_eq!(r.len(), 0);
            assert_eq!(r.is_empty(), true);
            assert_eq!(r.is_full(), true);
        }

        #[test]
        fn recv() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    assert_eq!(r.recv(), Some(7));
                    thread::sleep(ms(1000));
                    assert_eq!(r.recv(), Some(8));
                    thread::sleep(ms(1000));
                    assert_eq!(r.recv(), Some(9));
                    assert_eq!(r.recv(), None);
                });
                scope.spawn(move || {
                    thread::sleep(ms(1500));
                    s.send(7);
                    s.send(8);
                    s.send(9);
                });
            });
        }

        #[test]
        fn recv_timeout() {
            let (s, r) = channel::bounded::<i32>(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    select! {
                        recv(r) => panic!(),
                        recv(channel::after(ms(1000))) => {}
                    }
                    select! {
                        recv(r, v) => assert_eq!(v, Some(7)),
                        recv(channel::after(ms(1000))) => panic!(),
                    }
                    select! {
                        recv(r, v) => assert_eq!(v, None),
                        recv(channel::after(ms(1000))) => panic!(),
                    }
                });
                scope.spawn(move || {
                    thread::sleep(ms(1500));
                    s.send(7);
                });
            });
        }

        #[test]
        fn try_recv() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    assert_eq!(r.try_recv(), None);
                    thread::sleep(ms(1500));
                    assert_eq!(r.try_recv(), Some(7));
                    thread::sleep(ms(500));
                    assert_eq!(r.try_recv(), None);
                });
                scope.spawn(move || {
                    thread::sleep(ms(1000));
                    s.send(7);
                });
            });
        }

        #[test]
        fn send() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    s.send(7);
                    thread::sleep(ms(1000));
                    s.send(8);
                    thread::sleep(ms(1000));
                    s.send(9);
                });
                scope.spawn(move || {
                    thread::sleep(ms(1500));
                    assert_eq!(r.recv(), Some(7));
                    assert_eq!(r.recv(), Some(8));
                    assert_eq!(r.recv(), Some(9));
                });
            });
        }

        #[test]
        fn send_timeout() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    select! {
                        send(s, 7) => panic!(),
                        recv(channel::after(ms(1000))) => {}
                    }
                    select! {
                        send(s, 8) => {}
                        recv(channel::after(ms(1000))) => panic!(),
                    }
                    select! {
                        send(s, 9) => panic!(),
                        recv(channel::after(ms(1000))) => {}
                    }
                });
                scope.spawn(move || {
                    thread::sleep(ms(1500));
                    assert_eq!(r.recv(), Some(8));
                });
            });
        }

        #[test]
        fn try_send() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    select! {
                        send(s, 7) => panic!(),
                        default => {}
                    }
                    thread::sleep(ms(1500));
                    select! {
                        send(s, 8) => {}
                        default => panic!(),
                    }
                    thread::sleep(ms(500));
                    select! {
                        send(s, 9) => panic!(),
                        default => {}
                    }
                });
                scope.spawn(move || {
                    thread::sleep(ms(1000));
                    assert_eq!(r.recv(), Some(8));
                });
            });
        }

        #[test]
        fn len() {
            const COUNT: usize = 25_000;

            let (s, r) = channel::bounded(0);

            assert_eq!(s.len(), 0);
            assert_eq!(r.len(), 0);

            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    for i in 0..COUNT {
                        assert_eq!(r.recv(), Some(i));
                        assert_eq!(r.len(), 0);
                    }
                });

                scope.spawn(|| {
                    for i in 0..COUNT {
                        s.send(i);
                        assert_eq!(s.len(), 0);
                    }
                });
            });

            assert_eq!(s.len(), 0);
            assert_eq!(r.len(), 0);
        }

        #[test]
        fn close_signals_receiver() {
            let (s, r) = channel::bounded::<()>(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    assert_eq!(r.recv(), None);
                });
                scope.spawn(move || {
                    thread::sleep(ms(1000));
                    drop(s);
                });
            });
        }

        #[test]
        fn spsc() {
            const COUNT: usize = 100_000;

            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(move || {
                    for i in 0..COUNT {
                        assert_eq!(r.recv(), Some(i));
                    }
                    assert_eq!(r.recv(), None);
                });
                scope.spawn(move || {
                    for i in 0..COUNT {
                        s.send(i);
                    }
                });
            });
        }

        #[test]
        fn mpmc() {
            const COUNT: usize = 25_000;
            const THREADS: usize = 4;

            let (s, r) = channel::bounded::<usize>(0);
            let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>();

            crossbeam::scope(|scope| {
                for _ in 0..THREADS {
                    scope.spawn(|| {
                        for _ in 0..COUNT {
                            let n = r.recv().unwrap();
                            v[n].fetch_add(1, Ordering::SeqCst);
                        }
                    });
                }
                for _ in 0..THREADS {
                    scope.spawn(|| {
                        for i in 0..COUNT {
                            s.send(i);
                        }
                    });
                }
            });

            for c in v {
                assert_eq!(c.load(Ordering::SeqCst), THREADS);
            }
        }

        #[test]
        fn stress_timeout_two_threads() {
            const COUNT: usize = 100;

            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    for i in 0..COUNT {
                        if i % 2 == 0 {
                            thread::sleep(ms(50));
                        }
                        loop {
                            select! {
                                send(s, i) => break,
                                recv(channel::after(ms(10))) => {}
                            }
                        }
                    }
                });

                scope.spawn(|| {
                    for i in 0..COUNT {
                        if i % 2 == 0 {
                            thread::sleep(ms(50));
                        }
                        loop {
                            select! {
                                recv(r, v) => {
                                    assert_eq!(v, Some(i));
                                    break;
                                }
                                recv(channel::after(ms(10))) => {}
                            }
                        }
                    }
                });
            });
        }

        #[test]
        fn drops() {
            static DROPS: AtomicUsize = AtomicUsize::new(0);

            #[derive(Debug, PartialEq)]
            struct DropCounter;

            impl Drop for DropCounter {
                fn drop(&mut self) {
                    DROPS.fetch_add(1, Ordering::SeqCst);
                }
            }

            let mut rng = thread_rng();

            for _ in 0..100 {
                let steps = rng.gen_range(0, 3_000);

                DROPS.store(0, Ordering::SeqCst);
                let (s, r) = channel::bounded::<DropCounter>(0);

                crossbeam::scope(|scope| {
                    scope.spawn(|| {
                        for _ in 0..steps {
                            r.recv().unwrap();
                        }
                    });

                    scope.spawn(|| {
                        for _ in 0..steps {
                            s.send(DropCounter);
                        }
                    });
                });

                assert_eq!(DROPS.load(Ordering::SeqCst), steps);
                drop(s);
                drop(r);
                assert_eq!(DROPS.load(Ordering::SeqCst), steps);
            }
        }

        #[test]
        fn fairness() {
            const COUNT: usize = 10_000;

            let (s1, r1) = channel::bounded::<()>(0);
            let (s2, r2) = channel::bounded::<()>(0);

            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let mut hits = [0usize; 2];
                    for _ in 0..COUNT {
                        select! {
                            recv(r1) => hits[0] += 1,
                            recv(r2) => hits[1] += 1,
                        }
                    }
                    assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
                });

                let mut hits = [0usize; 2];
                for _ in 0..COUNT {
                    select! {
                        send(s1, ()) => hits[0] += 1,
                        send(s2, ()) => hits[1] += 1,
                    }
                }
                assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
            });
        }

        #[test]
        fn fairness_duplicates() {
            const COUNT: usize = 10_000;

            let (s, r) = channel::bounded::<()>(0);

            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let mut hits = [0usize; 5];
                    for _ in 0..COUNT {
                        select! {
                            recv(r) => hits[0] += 1,
                            recv(r) => hits[1] += 1,
                            recv(r) => hits[2] += 1,
                            recv(r) => hits[3] += 1,
                            recv(r) => hits[4] += 1,
                        }
                    }
                    assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
                });

                let mut hits = [0usize; 5];
                for _ in 0..COUNT {
                    select! {
                        send(s, ()) => hits[0] += 1,
                        send(s, ()) => hits[1] += 1,
                        send(s, ()) => hits[2] += 1,
                        send(s, ()) => hits[3] += 1,
                        send(s, ()) => hits[4] += 1,
                    }
                }
                assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
            });
        }

        #[test]
        fn recv_in_send() {
            let (s, r) = channel::bounded(0);

            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    thread::sleep(ms(100));
                    r.recv()
                });

                scope.spawn(|| {
                    thread::sleep(ms(500));
                    s.send(());
                });

                select! {
                    send(s, r.recv().unwrap()) => {}
                }
            });
        }
    };
}

mod normal {
    tests!(wrappers::normal);
}

mod select {
    tests!(wrappers::select);
}

mod select_spin {
    tests!(wrappers::select_spin);
}

mod select_multi {
    tests!(wrappers::select_multi);
}
<|endoftext|>