<commit_before>use std::{
    cell::{Cell, RefCell},
    fs,
    path::{Path, PathBuf},
    sync::Once,
    time::Duration,
};

use crossbeam_channel::{after, select, Receiver};
use lsp_server::{Connection, Message, Notification, Request};
use lsp_types::{
    notification::Exit, request::Shutdown, TextDocumentIdentifier, Url, WorkDoneProgress,
};
use lsp_types::{ProgressParams, ProgressParamsValue};
use ra_project_model::ProjectManifest;
use rust_analyzer::{
    config::{ClientCapsConfig, Config, FilesConfig, FilesWatcher, LinkedProject},
    main_loop,
};
use serde::Serialize;
use serde_json::{to_string_pretty, Value};
use test_utils::{find_mismatch, Fixture};
use vfs::AbsPathBuf;

use crate::testdir::TestDir;

pub struct Project<'a> {
    fixture: &'a str,
    with_sysroot: bool,
    tmp_dir: Option<TestDir>,
    roots: Vec<PathBuf>,
    config: Option<Box<dyn Fn(&mut Config)>>,
}

impl<'a> Project<'a> {
    pub fn with_fixture(fixture: &str) -> Project {
        Project { fixture, tmp_dir: None, roots: vec![], with_sysroot: false, config: None }
    }

    pub fn tmp_dir(mut self, tmp_dir: TestDir) -> Project<'a> {
        self.tmp_dir = Some(tmp_dir);
        self
    }

    pub(crate) fn root(mut self, path: &str) -> Project<'a> {
        self.roots.push(path.into());
        self
    }

    pub fn with_sysroot(mut self, sysroot: bool) -> Project<'a> {
        self.with_sysroot = sysroot;
        self
    }

    pub fn with_config(mut self, config: impl Fn(&mut Config) + 'static) -> Project<'a> {
        self.config = Some(Box::new(config));
        self
    }

    pub fn server(self) -> Server {
        let tmp_dir = self.tmp_dir.unwrap_or_else(|| TestDir::new());
        static INIT: Once = Once::new();
        INIT.call_once(|| {
            env_logger::builder().is_test(true).try_init().unwrap();
            ra_prof::init_from(crate::PROFILE);
        });

        for entry in Fixture::parse(self.fixture) {
            let path = tmp_dir.path().join(&entry.path['/'.len_utf8()..]);
            fs::create_dir_all(path.parent().unwrap()).unwrap();
            fs::write(path.as_path(), entry.text.as_bytes()).unwrap();
        }

        let tmp_dir_path = AbsPathBuf::assert(tmp_dir.path().to_path_buf());
        let mut roots =
            self.roots.into_iter().map(|root| tmp_dir_path.join(root)).collect::<Vec<_>>();
        if roots.is_empty() {
            roots.push(tmp_dir_path.clone());
        }
        let linked_projects = roots
            .into_iter()
            .map(|it| ProjectManifest::discover_single(&it).unwrap())
            .map(LinkedProject::from)
            .collect::<Vec<_>>();

        let mut config = Config {
            client_caps: ClientCapsConfig {
                location_link: true,
                code_action_literals: true,
                work_done_progress: true,
                ..Default::default()
            },
            with_sysroot: self.with_sysroot,
            linked_projects,
            files: FilesConfig { watcher: FilesWatcher::Client, exclude: Vec::new() },
            ..Config::new(tmp_dir_path)
        };
        if let Some(f) = &self.config {
            f(&mut config)
        }

        Server::new(tmp_dir, config)
    }
}

pub fn project(fixture: &str) -> Server {
    Project::with_fixture(fixture).server()
}

pub struct Server {
    req_id: Cell<u64>,
    messages: RefCell<Vec<Message>>,
    _thread: jod_thread::JoinHandle<()>,
    client: Connection,
    /// XXX: remove the tempdir last
    dir: TestDir,
}

impl Server {
    fn new(dir: TestDir, config: Config) -> Server {
        let (connection, client) = Connection::memory();

        let _thread = jod_thread::Builder::new()
            .name("test server".to_string())
            .spawn(move || main_loop(config, connection).unwrap())
            .expect("failed to spawn a thread");

        Server { req_id: Cell::new(1), dir, messages: Default::default(), client, _thread }
    }

    pub fn doc_id(&self, rel_path: &str) -> TextDocumentIdentifier {
        let path = self.dir.path().join(rel_path);
        TextDocumentIdentifier { uri: Url::from_file_path(path).unwrap() }
    }

    pub fn notification<N>(&self, params: N::Params)
    where
        N: lsp_types::notification::Notification,
        N::Params: Serialize,
    {
        let r = Notification::new(N::METHOD.to_string(), params);
        self.send_notification(r)
    }

    pub fn request<R>(&self, params: R::Params, expected_resp: Value)
    where
        R: lsp_types::request::Request,
        R::Params: Serialize,
    {
        let actual = self.send_request::<R>(params);
        if let Some((expected_part, actual_part)) = find_mismatch(&expected_resp, &actual) {
            panic!(
                "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n",
                to_string_pretty(&expected_resp).unwrap(),
                to_string_pretty(&actual).unwrap(),
                to_string_pretty(expected_part).unwrap(),
                to_string_pretty(actual_part).unwrap(),
            );
        }
    }

    pub fn send_request<R>(&self, params: R::Params) -> Value
    where
        R: lsp_types::request::Request,
        R::Params: Serialize,
    {
        let id = self.req_id.get();
        self.req_id.set(id + 1);

        let r = Request::new(id.into(), R::METHOD.to_string(), params);
        self.send_request_(r)
    }
    fn send_request_(&self, r: Request) -> Value {
        let id = r.id.clone();
        self.client.sender.send(r.into()).unwrap();
        while let Some(msg) = self.recv() {
            match msg {
                Message::Request(req) => {
                    if req.method == "window/workDoneProgress/create" {
                        continue;
                    }
                    if req.method == "client/registerCapability" {
                        let params = req.params.to_string();
                        if ["workspace/didChangeWatchedFiles", "textDocument/didSave"]
                            .iter()
                            .any(|&it| params.contains(it))
                        {
                            continue;
                        }
                    }
                    panic!("unexpected request: {:?}", req)
                }
                Message::Notification(_) => (),
                Message::Response(res) => {
                    assert_eq!(res.id, id);
                    if let Some(err) = res.error {
                        panic!("error response: {:#?}", err);
                    }
                    return res.result.unwrap();
                }
            }
        }
        panic!("no response");
    }
    pub fn wait_until_workspace_is_loaded(&self) {
        self.wait_for_message_cond(1, &|msg: &Message| match msg {
            Message::Notification(n) if n.method == "$/progress" => {
                match n.clone().extract::<ProgressParams>("$/progress").unwrap() {
                    ProgressParams {
                        token: lsp_types::ProgressToken::String(ref token),
                        value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(_)),
                    } if token == "rustAnalyzer/roots scanned" => true,
                    _ => false,
                }
            }
            _ => false,
        })
    }
    fn wait_for_message_cond(&self, n: usize, cond: &dyn Fn(&Message) -> bool) {
        let mut total = 0;
        for msg in self.messages.borrow().iter() {
            if cond(msg) {
                total += 1
            }
        }
        while total < n {
            let msg = self.recv().expect("no response");
            if cond(&msg) {
                total += 1;
            }
        }
    }
    fn recv(&self) -> Option<Message> {
        recv_timeout(&self.client.receiver).map(|msg| {
            self.messages.borrow_mut().push(msg.clone());
            msg
        })
    }
    fn send_notification(&self, not: Notification) {
        self.client.sender.send(Message::Notification(not)).unwrap();
    }

    pub fn path(&self) -> &Path {
        self.dir.path()
    }
}

impl Drop for Server {
    fn drop(&mut self) {
        self.request::<Shutdown>((), Value::Null);
        self.notification::<Exit>(());
    }
}

fn recv_timeout(receiver: &Receiver<Message>) -> Option<Message> {
    let timeout = Duration::from_secs(120);
    select! {
        recv(receiver) -> msg => msg.ok(),
        recv(after(timeout)) -> _ => panic!("timed out"),
    }
}
<commit_msg>Bump test timeout for macs<commit_after>use std::{
    cell::{Cell, RefCell},
    fs,
    path::{Path, PathBuf},
    sync::Once,
    time::Duration,
};

use crossbeam_channel::{after, select, Receiver};
use lsp_server::{Connection, Message, Notification, Request};
use lsp_types::{
    notification::Exit, request::Shutdown, TextDocumentIdentifier, Url, WorkDoneProgress,
};
use lsp_types::{ProgressParams, ProgressParamsValue};
use ra_project_model::ProjectManifest;
use rust_analyzer::{
    config::{ClientCapsConfig, Config, FilesConfig, FilesWatcher, LinkedProject},
    main_loop,
};
use serde::Serialize;
use serde_json::{to_string_pretty, Value};
use test_utils::{find_mismatch, Fixture};
use vfs::AbsPathBuf;

use crate::testdir::TestDir;

pub struct Project<'a> {
    fixture: &'a str,
    with_sysroot: bool,
    tmp_dir: Option<TestDir>,
    roots: Vec<PathBuf>,
    config: Option<Box<dyn Fn(&mut Config)>>,
}

impl<'a> Project<'a> {
    pub fn with_fixture(fixture: &str) -> Project {
        Project { fixture, tmp_dir: None, roots: vec![], with_sysroot: false, config: None }
    }

    pub fn tmp_dir(mut self, tmp_dir: TestDir) -> Project<'a> {
        self.tmp_dir = Some(tmp_dir);
        self
    }

    pub(crate) fn root(mut self, path: &str) -> Project<'a> {
        self.roots.push(path.into());
        self
    }

    pub fn with_sysroot(mut self, sysroot: bool) -> Project<'a> {
        self.with_sysroot = sysroot;
        self
    }

    pub fn with_config(mut self, config: impl Fn(&mut Config) + 'static) -> Project<'a> {
        self.config = Some(Box::new(config));
        self
    }

    pub fn server(self) -> Server {
        let tmp_dir = self.tmp_dir.unwrap_or_else(|| TestDir::new());
        static INIT: Once = Once::new();
        INIT.call_once(|| {
            env_logger::builder().is_test(true).try_init().unwrap();
            ra_prof::init_from(crate::PROFILE);
        });

        for entry in Fixture::parse(self.fixture) {
            let path = tmp_dir.path().join(&entry.path['/'.len_utf8()..]);
            fs::create_dir_all(path.parent().unwrap()).unwrap();
            fs::write(path.as_path(), entry.text.as_bytes()).unwrap();
        }

        let tmp_dir_path = AbsPathBuf::assert(tmp_dir.path().to_path_buf());
        let mut roots =
            self.roots.into_iter().map(|root| tmp_dir_path.join(root)).collect::<Vec<_>>();
        if roots.is_empty() {
            roots.push(tmp_dir_path.clone());
        }
        let linked_projects = roots
            .into_iter()
            .map(|it| ProjectManifest::discover_single(&it).unwrap())
            .map(LinkedProject::from)
            .collect::<Vec<_>>();

        let mut config = Config {
            client_caps: ClientCapsConfig {
                location_link: true,
                code_action_literals: true,
                work_done_progress: true,
                ..Default::default()
            },
            with_sysroot: self.with_sysroot,
            linked_projects,
            files: FilesConfig { watcher: FilesWatcher::Client, exclude: Vec::new() },
            ..Config::new(tmp_dir_path)
        };
        if let Some(f) = &self.config {
            f(&mut config)
        }

        Server::new(tmp_dir, config)
    }
}

pub fn project(fixture: &str) -> Server {
    Project::with_fixture(fixture).server()
}

pub struct Server {
    req_id: Cell<u64>,
    messages: RefCell<Vec<Message>>,
    _thread: jod_thread::JoinHandle<()>,
    client: Connection,
    /// XXX: remove the tempdir last
    dir: TestDir,
}

impl Server {
    fn new(dir: TestDir, config: Config) -> Server {
        let (connection, client) = Connection::memory();

        let _thread = jod_thread::Builder::new()
            .name("test server".to_string())
            .spawn(move || main_loop(config, connection).unwrap())
            .expect("failed to spawn a thread");

        Server { req_id: Cell::new(1), dir, messages: Default::default(), client, _thread }
    }

    pub fn doc_id(&self, rel_path: &str) -> TextDocumentIdentifier {
        let path = self.dir.path().join(rel_path);
        TextDocumentIdentifier { uri: Url::from_file_path(path).unwrap() }
    }

    pub fn notification<N>(&self, params: N::Params)
    where
        N: lsp_types::notification::Notification,
        N::Params: Serialize,
    {
        let r = Notification::new(N::METHOD.to_string(), params);
        self.send_notification(r)
    }

    pub fn request<R>(&self, params: R::Params, expected_resp: Value)
    where
        R: lsp_types::request::Request,
        R::Params: Serialize,
    {
        let actual = self.send_request::<R>(params);
        if let Some((expected_part, actual_part)) = find_mismatch(&expected_resp, &actual) {
            panic!(
                "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n",
                to_string_pretty(&expected_resp).unwrap(),
                to_string_pretty(&actual).unwrap(),
                to_string_pretty(expected_part).unwrap(),
                to_string_pretty(actual_part).unwrap(),
            );
        }
    }

    pub fn send_request<R>(&self, params: R::Params) -> Value
    where
        R: lsp_types::request::Request,
        R::Params: Serialize,
    {
        let id = self.req_id.get();
        self.req_id.set(id + 1);

        let r = Request::new(id.into(), R::METHOD.to_string(), params);
        self.send_request_(r)
    }
    fn send_request_(&self, r: Request) -> Value {
        let id = r.id.clone();
        self.client.sender.send(r.into()).unwrap();
        while let Some(msg) = self.recv() {
            match msg {
                Message::Request(req) => {
                    if req.method == "window/workDoneProgress/create" {
                        continue;
                    }
                    if req.method == "client/registerCapability" {
                        let params = req.params.to_string();
                        if ["workspace/didChangeWatchedFiles", "textDocument/didSave"]
                            .iter()
                            .any(|&it| params.contains(it))
                        {
                            continue;
                        }
                    }
                    panic!("unexpected request: {:?}", req)
                }
                Message::Notification(_) => (),
                Message::Response(res) => {
                    assert_eq!(res.id, id);
                    if let Some(err) = res.error {
                        panic!("error response: {:#?}", err);
                    }
                    return res.result.unwrap();
                }
            }
        }
        panic!("no response");
    }
    pub fn wait_until_workspace_is_loaded(&self) {
        self.wait_for_message_cond(1, &|msg: &Message| match msg {
            Message::Notification(n) if n.method == "$/progress" => {
                match n.clone().extract::<ProgressParams>("$/progress").unwrap() {
                    ProgressParams {
                        token: lsp_types::ProgressToken::String(ref token),
                        value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(_)),
                    } if token == "rustAnalyzer/roots scanned" => true,
                    _ => false,
                }
            }
            _ => false,
        })
    }
    fn wait_for_message_cond(&self, n: usize, cond: &dyn Fn(&Message) -> bool) {
        let mut total = 0;
        for msg in self.messages.borrow().iter() {
            if cond(msg) {
                total += 1
            }
        }
        while total < n {
            let msg = self.recv().expect("no response");
            if cond(&msg) {
                total += 1;
            }
        }
    }
    fn recv(&self) -> Option<Message> {
        recv_timeout(&self.client.receiver).map(|msg| {
            self.messages.borrow_mut().push(msg.clone());
            msg
        })
    }
    fn send_notification(&self, not: Notification) {
        self.client.sender.send(Message::Notification(not)).unwrap();
    }

    pub fn path(&self) -> &Path {
        self.dir.path()
    }
}

impl Drop for Server {
    fn drop(&mut self) {
        self.request::<Shutdown>((), Value::Null);
        self.notification::<Exit>(());
    }
}

fn recv_timeout(receiver: &Receiver<Message>) -> Option<Message> {
    let timeout =
        if cfg!(target_os = "macos") { Duration::from_secs(300) } else { Duration::from_secs(120) };
    select! {
        recv(receiver) -> msg => msg.ok(),
        recv(after(timeout)) -> _ => panic!("timed out"),
    }
}
<|endoftext|>


<commit_before>// {
//   Derived from : Bjoern Hoehrmann work
//   Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
//   See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.

pub const UTF8_ACCEPT: u32 = 0;
pub const UTF8_REJECT: u32 = 1;

static UTF8D: &'static [u8] = &[
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
  8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
  0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
  0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
  0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
  1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
  1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
  1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
];

/*
    state UTF8_ACCEPT => initial state or decoding successful
    state UTF8_REJECT => error
    state other => intermediate states need more inputs
*/
#[inline]
pub fn decode_byte(state: u32, byte: u8, codep: &mut u32) -> u32 {
    let cp_type = UTF8D[byte as usize] as u32;

    *codep = if state != UTF8_ACCEPT {
        (byte & 0x3f) as u32 | (*codep << 6)
    } else {
        (0xff >> cp_type) as u32 & (byte as u32)
    };

    UTF8D[256 + (state * 16) as usize + cp_type as usize] as u32
}

// }

#[inline]
pub fn is_codepoint_start(byte: u8) -> bool {
    if byte < 0x80 {
        return true;
    }

    if byte >= 0xC2 && byte <= 0xDF {
        return true;
    }

    if byte >= 0xC2 && byte <= 0xDF {
        return true;
    }

    if byte >= 0xE0 && byte <= 0xEC {
        return true;
    }

    if byte >= 0xED && byte <= 0xEF {
        return true;
    }

    if byte >= 0xF0 && byte <= 0xF4 {
        return true;
    }

    false
}

// return 0 on error, or the number of written bytes
pub fn encode(codepoint: u32, out: &mut [u8; 4]) -> usize {
    if codepoint < 0x80 {
        out[0] = codepoint as u8;
        return 1;
    }

    if codepoint < 0x800 {
        out[0] = 0xC0 | (codepoint >> 6) as u8;
        out[1] = 0x80 | (codepoint & 0x3F) as u8;
        return 2;
    }

    if codepoint < 0xFFFF {
        out[0] = 0xE0 | (codepoint >> 12) as u8;
        out[1] = 0x80 | (codepoint >> 6) as u8;
        out[2] = 0x80 | (codepoint & 0x3F) as u8;
        return 3;
    }

    if codepoint < 0x10FFFF {
        out[0] = 0xF0 | (codepoint >> 18) as u8;
        out[1] = 0x80 | (codepoint >> 12) as u8;
        out[2] = 0x80 | (codepoint >> 6) as u8;
        out[3] = 0x80 | (codepoint & 0x3F) as u8;
        return 4;
    }

    0
}

// TODO: change this with temporary (cp, offset, size) until from_offset
pub fn get_previous_codepoint_start(data: &[u8], from_offset: u64) -> u64 {
    //                 cp    size   offset
    let mut cp_info: [(char, usize, u64); 8] = [
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
    ];
    let mut nr_cpinfo = 0;

    // rewind up to 4 bytes
    // and decode forward / save offset
    let mut off = if from_offset > 4 { from_offset - 4 } else { 0 };
    while off < from_offset {
        let (cp, _, size) = get_codepoint(data, off);

        cp_info[nr_cpinfo] = (cp, size, off);
        nr_cpinfo += 1;

        off += size as u64;
    }

    if nr_cpinfo != 0 {
        cp_info[nr_cpinfo - 1].2
    } else {
        from_offset
    }
}

pub fn get_next_codepoint_start(data: &[u8], from_offset: u64) -> u64 {
    let (_, _, size) = get_codepoint(data, from_offset);
    from_offset + size as u64
}

pub fn get_codepoint(data: &[u8], from_offset: u64) -> (char, u64, usize) {
    let mut state = 0;
    let mut codep = 0;
    let mut size = 0;

    for b in data.iter().skip(from_offset as usize) {
        size += 1;
        state = decode_byte(state, *b, &mut codep);
        match state {
            0 => {
                break;
            }
            1 => {
                // decode error : invalid sequence
                codep = 0xfffd;
                size = 1; // force restart @ next byte
                break;
            }
            _ => {}
        }
    }

    // TODO return Result<(char, usize), status> -> state != 1|0 -> need mode data
    (::core::codec::text::u32_to_char(codep), from_offset, size)
}

pub fn get_prev_codepoint(data: &[u8], from_offset: u64) -> (char, u64, usize) {
    let offset = get_previous_codepoint_start(data, from_offset);
    get_codepoint(data, offset)
}

#[test]
fn test_codec_encode() {
    let expect_cp: [u8; 4] = [0xe2, 0x82, 0xac, 0x00];
    let mut mut_cp: [u8; 4] = [0x00, 0x00, 0x00, 0x00];

    let n = encode(0x20ac as u32, &mut mut_cp);
    assert_eq!(n, 3);
    assert_eq!(mut_cp, expect_cp);
}

#[test]
fn test_codec_decode() {
    use core::codec::text::u32_to_char;

    let mut state: u32 = 0;
    let mut codep: u32 = 0;

    let sequence: [u8; 4] = [0xe2, 0x82, 0xac, 0x00];
    for b in &sequence {
        println!("decode byte '{:x}'", *b);
        state = decode_byte(state, *b, &mut codep);
        match state {
            UTF8_ACCEPT => {
                break;
            }
            UTF8_REJECT => {
                println!("invalid utf8 sequence");
                break;
            }
            _ => {
                continue;
            }
        }
    }

    println!("decoded codepoint value {:x}", codep);
    let c = u32_to_char(codep);
    println!("decoded codepoint char {}", c);

    assert_eq!(codep, 0x20ac);
}

#[test]
fn test2_codec_decode() {
    let data: [u8; 27] = [
        0xe2, 0x82, 0xac, 0xe2, 0x82, 0x61, 0x0a, 0x82, 0xac, 0xe2, 0x82, 0x61, 0x0a, 0xac, 0xe2,
        0x82, 0x61, 0x0a, 0xe2, 0x82, 0x61, 0x0a, 0x82, 0x61, 0x0a, 0x61, 0x0a,
    ];

    let mut state: u32 = 0;
    let mut codep: u32 = 0;

    for b in &data {
        println!("decode byte '{:x}'", *b);
        state = decode_byte(state, *b, &mut codep);
        println!("state  '{}'", state);
        match state {
            UTF8_ACCEPT => {
                println!("decoded cp = '{:?}'", codep);
                state = 0;
                codep = 0;
            }
            UTF8_REJECT => {
                println!("invalid utf8 sequence, restart");
                state = 0;
                codep = 0;
                state = decode_byte(state, *b, &mut codep);
                match state {
                    UTF8_ACCEPT => {
                        println!("decoded cp = '{:?}'", codep);
                        state = 0;
                        codep = 0;
                    }
                    UTF8_REJECT => {
                        println!("invalid utf8 sequence, restart");
                        state = 0;
                        codep = 0;
                    }
                    _ => {}
                }
            }

            _ => {
                continue;
            }
        }
    }
}
<commit_msg>utf8 : add test test_backward_decode()<commit_after>// {
//   Derived from : Bjoern Hoehrmann work
//   Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
//   See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.

pub const UTF8_ACCEPT: u32 = 0;
pub const UTF8_REJECT: u32 = 1;

static UTF8D: &'static [u8] = &[
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
  8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
  0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
  0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
  0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
  1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
  1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
  1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
];

/*
    state UTF8_ACCEPT => initial state or decoding successful
    state UTF8_REJECT => error
    state other => intermediate states need more inputs
*/
#[inline]
pub fn decode_byte(state: u32, byte: u8, codep: &mut u32) -> u32 {
    let cp_type = UTF8D[byte as usize] as u32;

    *codep = if state != UTF8_ACCEPT {
        (byte & 0x3f) as u32 | (*codep << 6)
    } else {
        (0xff >> cp_type) as u32 & (byte as u32)
    };

    UTF8D[256 + (state * 16) as usize + cp_type as usize] as u32
}

// }

#[inline]
pub fn is_codepoint_start(byte: u8) -> bool {
    if byte < 0x80 {
        return true;
    }

    if byte >= 0xC2 && byte <= 0xDF {
        return true;
    }

    if byte >= 0xC2 && byte <= 0xDF {
        return true;
    }

    if byte >= 0xE0 && byte <= 0xEC {
        return true;
    }

    if byte >= 0xED && byte <= 0xEF {
        return true;
    }

    if byte >= 0xF0 && byte <= 0xF4 {
        return true;
    }

    false
}

// return 0 on error, or the number of written bytes
pub fn encode(codepoint: u32, out: &mut [u8; 4]) -> usize {
    if codepoint < 0x80 {
        out[0] = codepoint as u8;
        return 1;
    }

    if codepoint < 0x800 {
        out[0] = 0xC0 | (codepoint >> 6) as u8;
        out[1] = 0x80 | (codepoint & 0x3F) as u8;
        return 2;
    }

    if codepoint < 0xFFFF {
        out[0] = 0xE0 | (codepoint >> 12) as u8;
        out[1] = 0x80 | (codepoint >> 6) as u8;
        out[2] = 0x80 | (codepoint & 0x3F) as u8;
        return 3;
    }

    if codepoint < 0x10FFFF {
        out[0] = 0xF0 | (codepoint >> 18) as u8;
        out[1] = 0x80 | (codepoint >> 12) as u8;
        out[2] = 0x80 | (codepoint >> 6) as u8;
        out[3] = 0x80 | (codepoint & 0x3F) as u8;
        return 4;
    }

    0
}

// TODO: change this with temporary (cp, offset, size) until from_offset
pub fn get_previous_codepoint_start(data: &[u8], from_offset: u64) -> u64 {
    //                 cp    size   offset
    let mut cp_info: [(char, usize, u64); 8] = [
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
        ('\0', 0, 0),
    ];
    let mut nr_cpinfo = 0;

    // rewind up to 4 bytes
    // and decode forward / save offset
    let mut off = if from_offset > 4 { from_offset - 4 } else { 0 };
    while off < from_offset {
        let (cp, _, size) = get_codepoint(data, off);

        cp_info[nr_cpinfo] = (cp, size, off);
        nr_cpinfo += 1;

        off += size as u64;
    }

    if nr_cpinfo != 0 {
        cp_info[nr_cpinfo - 1].2
    } else {
        from_offset
    }
}

pub fn get_next_codepoint_start(data: &[u8], from_offset: u64) -> u64 {
    let (_, _, size) = get_codepoint(data, from_offset);
    from_offset + size as u64
}

pub fn get_codepoint(data: &[u8], from_offset: u64) -> (char, u64, usize) {
    let mut state = 0;
    let mut codep = 0;
    let mut size = 0;

    for b in data.iter().skip(from_offset as usize) {
        size += 1;
        state = decode_byte(state, *b, &mut codep);
        match state {
            0 => {
                break;
            }
            1 => {
                // decode error : invalid sequence
                codep = 0xfffd;
                size = 1; // force restart @ next byte
                break;
            }
            _ => {}
        }
    }

    // TODO return Result<(char, usize), status> -> state != 1|0 -> need mode data
    (::core::codec::text::u32_to_char(codep), from_offset, size)
}

pub fn get_prev_codepoint(data: &[u8], from_offset: u64) -> (char, u64, usize) {
    let offset = get_previous_codepoint_start(data, from_offset);
    get_codepoint(data, offset)
}

#[test]
fn test_codec_encode() {
    let expect_cp: [u8; 4] = [0xe2, 0x82, 0xac, 0x00];
    let mut mut_cp: [u8; 4] = [0x00, 0x00, 0x00, 0x00];

    let n = encode(0x20ac as u32, &mut mut_cp);
    assert_eq!(n, 3);
    assert_eq!(mut_cp, expect_cp);
}

#[test]
fn test_codec_decode() {
    use core::codec::text::u32_to_char;

    let mut state: u32 = 0;
    let mut codep: u32 = 0;

    let sequence: [u8; 4] = [0xe2, 0x82, 0xac, 0x00];
    for b in &sequence {
        println!("decode byte '{:x}'", *b);
        state = decode_byte(state, *b, &mut codep);
        match state {
            UTF8_ACCEPT => {
                break;
            }
            UTF8_REJECT => {
                println!("invalid utf8 sequence");
                break;
            }
            _ => {
                continue;
            }
        }
    }

    println!("decoded codepoint value {:x}", codep);
    let c = u32_to_char(codep);
    println!("decoded codepoint char {}", c);

    assert_eq!(codep, 0x20ac);
}

#[test]
fn test2_codec_decode() {
    let data: [u8; 27] = [
        0xe2, 0x82, 0xac, 0xe2, 0x82, 0x61, 0x0a, 0x82, 0xac, 0xe2, 0x82, 0x61, 0x0a, 0xac, 0xe2,
        0x82, 0x61, 0x0a, 0xe2, 0x82, 0x61, 0x0a, 0x82, 0x61, 0x0a, 0x61, 0x0a,
    ];

    let mut state: u32 = 0;
    let mut codep: u32 = 0;

    for b in &data {
        println!("decode byte '{:x}'", *b);
        state = decode_byte(state, *b, &mut codep);
        println!("state  '{}'", state);
        match state {
            UTF8_ACCEPT => {
                println!("decoded cp = '{:?}'", codep);
                state = 0;
                codep = 0;
            }
            UTF8_REJECT => {
                println!("invalid utf8 sequence, restart");
                state = 0;
                codep = 0;
                state = decode_byte(state, *b, &mut codep);
                match state {
                    UTF8_ACCEPT => {
                        println!("decoded cp = '{:?}'", codep);
                        state = 0;
                        codep = 0;
                    }
                    UTF8_REJECT => {
                        println!("invalid utf8 sequence, restart");
                        state = 0;
                        codep = 0;
                    }
                    _ => {}
                }
            }

            _ => {
                continue;
            }
        }
    }
}

#[test]
fn test_backward_decode() {
    let data: [u8; 24] = [
        0xe2, 0x82, 0xac, 0xe2, 0x82, 0xac, 0xe2, 0x82, 0xac, 0xe2, 0x82, 0xac, 0xe2, 0x82, 0xac,
        0xe2, 0x82, 0xac, 0xe2, 0x82, 0xac, 0xe2, 0x82, 0xac,
    ];

    let mut start_offset: u64 = 6;
    println!(
        "start_offset {} byte is '{:x}'",
        start_offset, data[start_offset as usize] as u32
    );

    let off = get_previous_codepoint_start(&data, start_offset as u64);
    println!(
        "start_offset({}) - off({}) = {}",
        start_offset,
        off,
        start_offset - off
    );
    let delta = start_offset - off;
    start_offset -= delta;

    println!("new start_offset({})", start_offset);
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(proc_macro)]

extern crate ipc_channel;
extern crate regex;
#[macro_use]
extern crate serde_derive;
extern crate util;

pub mod blocklist;
pub mod scanfilter;

use ipc_channel::ipc::IpcSender;
use scanfilter::RequestDeviceoptions;

#[derive(Deserialize, Serialize)]
pub enum BluetoothError {
    Type(String),
    Network,
    NotFound,
    NotSupported,
    Security,
    InvalidState,
}

#[derive(Deserialize, Serialize)]
pub struct BluetoothDeviceMsg {
    // Bluetooth Device properties
    pub id: String,
    pub name: Option<String>,
    // Advertisiong Data properties
    pub appearance: Option<u16>,
    pub tx_power: Option<i8>,
    pub rssi: Option<i8>,
}

#[derive(Deserialize, Serialize)]
pub struct BluetoothServiceMsg {
    pub uuid: String,
    pub is_primary: bool,
    pub instance_id: String,
}

#[derive(Deserialize, Serialize)]
pub struct BluetoothCharacteristicMsg {
    // Characteristic
    pub uuid: String,
    pub instance_id: String,
    // Characteristic properties
    pub broadcast: bool,
    pub read: bool,
    pub write_without_response: bool,
    pub write: bool,
    pub notify: bool,
    pub indicate: bool,
    pub authenticated_signed_writes: bool,
    pub reliable_write: bool,
    pub writable_auxiliaries: bool,
}

#[derive(Deserialize, Serialize)]
pub struct BluetoothDescriptorMsg {
    pub uuid: String,
    pub instance_id: String,
}

pub type BluetoothServicesMsg = Vec<BluetoothServiceMsg>;

pub type BluetoothCharacteristicsMsg = Vec<BluetoothCharacteristicMsg>;

pub type BluetoothDescriptorsMsg = Vec<BluetoothDescriptorMsg>;

pub type BluetoothResult<T> = Result<T, BluetoothError>;

pub type BluetoothResponseResult = Result<BluetoothResponse, BluetoothError>;

#[derive(Deserialize, Serialize)]
pub enum BluetoothRequest {
    RequestDevice(RequestDeviceoptions, IpcSender<BluetoothResponseResult>),
    GATTServerConnect(String, IpcSender<BluetoothResponseResult>),
    GATTServerDisconnect(String, IpcSender<BluetoothResult<bool>>),
    GetPrimaryService(String, String, IpcSender<BluetoothResponseResult>),
    GetPrimaryServices(String, Option<String>, IpcSender<BluetoothResponseResult>),
    GetIncludedService(String, String, IpcSender<BluetoothResponseResult>),
    GetIncludedServices(String, Option<String>, IpcSender<BluetoothResponseResult>),
    GetCharacteristic(String, String, IpcSender<BluetoothResponseResult>),
    GetCharacteristics(String, Option<String>, IpcSender<BluetoothResponseResult>),
    GetDescriptor(String, String, IpcSender<BluetoothResponseResult>),
    GetDescriptors(String, Option<String>, IpcSender<BluetoothResponseResult>),
    ReadValue(String, IpcSender<BluetoothResponseResult>),
    WriteValue(String, Vec<u8>, IpcSender<BluetoothResponseResult>),
    EnableNotification(String, bool, IpcSender<BluetoothResponseResult>),
    Test(String, IpcSender<BluetoothResult<()>>),
    Exit,
}

#[derive(Deserialize, Serialize)]
pub enum BluetoothResponse {
    RequestDevice(BluetoothDeviceMsg),
    GATTServerConnect(bool),
    GetPrimaryService(BluetoothServiceMsg),
    GetPrimaryServices(BluetoothServicesMsg),
    GetIncludedService(BluetoothServiceMsg),
    GetIncludedServices(BluetoothServicesMsg),
    GetCharacteristic(BluetoothCharacteristicMsg),
    GetCharacteristics(BluetoothCharacteristicsMsg),
    GetDescriptor(BluetoothDescriptorMsg),
    GetDescriptors(BluetoothDescriptorsMsg),
    ReadValue(Vec<u8>),
    WriteValue(Vec<u8>),
    EnableNotification(()),
}

pub trait BluetoothResponseListener {
    fn response(&mut self, response: BluetoothResponseResult);
}
<commit_msg>Auto merge of #14392 - zakorgy:patch-2, r=Ms2ger<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(proc_macro)]

extern crate ipc_channel;
extern crate regex;
#[macro_use]
extern crate serde_derive;
extern crate util;

pub mod blocklist;
pub mod scanfilter;

use ipc_channel::ipc::IpcSender;
use scanfilter::RequestDeviceoptions;

#[derive(Deserialize, Serialize)]
pub enum BluetoothError {
    Type(String),
    Network,
    NotFound,
    NotSupported,
    Security,
    InvalidState,
}

#[derive(Deserialize, Serialize)]
pub struct BluetoothDeviceMsg {
    // Bluetooth Device properties
    pub id: String,
    pub name: Option<String>,
    // Advertising Data properties
    pub appearance: Option<u16>,
    pub tx_power: Option<i8>,
    pub rssi: Option<i8>,
}

#[derive(Deserialize, Serialize)]
pub struct BluetoothServiceMsg {
    pub uuid: String,
    pub is_primary: bool,
    pub instance_id: String,
}

#[derive(Deserialize, Serialize)]
pub struct BluetoothCharacteristicMsg {
    // Characteristic
    pub uuid: String,
    pub instance_id: String,
    // Characteristic properties
    pub broadcast: bool,
    pub read: bool,
    pub write_without_response: bool,
    pub write: bool,
    pub notify: bool,
    pub indicate: bool,
    pub authenticated_signed_writes: bool,
    pub reliable_write: bool,
    pub writable_auxiliaries: bool,
}

#[derive(Deserialize, Serialize)]
pub struct BluetoothDescriptorMsg {
    pub uuid: String,
    pub instance_id: String,
}

pub type BluetoothServicesMsg = Vec<BluetoothServiceMsg>;

pub type BluetoothCharacteristicsMsg = Vec<BluetoothCharacteristicMsg>;

pub type BluetoothDescriptorsMsg = Vec<BluetoothDescriptorMsg>;

pub type BluetoothResult<T> = Result<T, BluetoothError>;

pub type BluetoothResponseResult = Result<BluetoothResponse, BluetoothError>;

#[derive(Deserialize, Serialize)]
pub enum BluetoothRequest {
    RequestDevice(RequestDeviceoptions, IpcSender<BluetoothResponseResult>),
    GATTServerConnect(String, IpcSender<BluetoothResponseResult>),
    GATTServerDisconnect(String, IpcSender<BluetoothResult<bool>>),
    GetPrimaryService(String, String, IpcSender<BluetoothResponseResult>),
    GetPrimaryServices(String, Option<String>, IpcSender<BluetoothResponseResult>),
    GetIncludedService(String, String, IpcSender<BluetoothResponseResult>),
    GetIncludedServices(String, Option<String>, IpcSender<BluetoothResponseResult>),
    GetCharacteristic(String, String, IpcSender<BluetoothResponseResult>),
    GetCharacteristics(String, Option<String>, IpcSender<BluetoothResponseResult>),
    GetDescriptor(String, String, IpcSender<BluetoothResponseResult>),
    GetDescriptors(String, Option<String>, IpcSender<BluetoothResponseResult>),
    ReadValue(String, IpcSender<BluetoothResponseResult>),
    WriteValue(String, Vec<u8>, IpcSender<BluetoothResponseResult>),
    EnableNotification(String, bool, IpcSender<BluetoothResponseResult>),
    Test(String, IpcSender<BluetoothResult<()>>),
    Exit,
}

#[derive(Deserialize, Serialize)]
pub enum BluetoothResponse {
    RequestDevice(BluetoothDeviceMsg),
    GATTServerConnect(bool),
    GetPrimaryService(BluetoothServiceMsg),
    GetPrimaryServices(BluetoothServicesMsg),
    GetIncludedService(BluetoothServiceMsg),
    GetIncludedServices(BluetoothServicesMsg),
    GetCharacteristic(BluetoothCharacteristicMsg),
    GetCharacteristics(BluetoothCharacteristicsMsg),
    GetDescriptor(BluetoothDescriptorMsg),
    GetDescriptors(BluetoothDescriptorsMsg),
    ReadValue(Vec<u8>),
    WriteValue(Vec<u8>),
    EnableNotification(()),
}

pub trait BluetoothResponseListener {
    fn response(&mut self, response: BluetoothResponseResult);
}
<|endoftext|>


<commit_before>//! Selection sort algorithm.
//!
//! The `selection` module contains the simple sorting algorithm "Selection Sort".
//!
//! Source: https://en.wikipedia.org/wiki/Selection_sort

use std::fmt::Debug;

/// Simple sort: selection sort.
///
/// # Details
///
/// Selection sort is one of the simplest sorting algorithm. The list to sort is split into two
/// sections; the first with the sorted element (starting empty) and the second with the remaining
/// element (starting full). At every iteration, the smallest element in the remaining list is
/// found and placed at the end of the sorted list.
///
/// This function takes an immutable reference vector of any type and returns a vector of `usize`
/// of the same length containing the indices of the initial vector sorted.
///
/// # Scaling
///
/// Selection sort in scale as O(N^2) since for all elements to sort, the algorithm will compare it
/// with every (remaining) elements.
///
/// Insertion sort is still useful as it is quite simple.
///
/// # Optimizations
///
/// None
///
/// # Notes
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let mut data: Vec<i32> = vec![4, 2, 3, 1, 5];
/// sorting::simplesorts::selection::sort(&mut data);
/// assert_eq!(vec![1, 2, 3, 4, 5], data);
/// ```
///
pub fn sort<T: Ord + Debug>(array: &mut Vec<T>) {
    println!("input array:  {:?}", array);

    if !array.is_empty() {
        // Let's loop over the input array, skipping last value (important as we want to get a
        // slice of the following values).
        let n = array.len();
        for i in 0..n-1 {
            println!("    i: {:?}", i);

            // Find index of the minimum value in the slice of values following the i^th element.
            let j = {
                let int_slice = &array[i+1..];
                println!("        array:        {:?}", array);
                println!("        int_slice:    {:?}", int_slice);
                // k now holds the index (of "array") of the minimum element of "int_slice", or the
                // value "i" of the current element of "array" (which should be the less than
                // all elements of "int_slice").
                // "k" is a tuple containing the smallest element of "int_slice" and its index.
                //     k.0: Index of "int_slice" of its smallest value.
                //     k.1: Smallest value of "int_slice".
                let k = int_slice.iter().enumerate().fold(
                    (0, int_slice.first().unwrap()), |acc, item| {
                        if acc.1 > item.1 { item } else { acc }
                });

                // Return from the block the smallest element between the one at index "i" of
                // the "array" and the smallest one from the "int_slice" array.
                // NOTE: Since "k" worked on the subarray "int_slice", it's first element is the
                //       i^th element of "array". If "k" is actually smaller than "array[i]", we
                //       need to adapt the index as stored in "k.0".
                if k.1 < &array[i] { i + k.0 + 1 } else { i }
            };
            println!("            k: {:?}   array[i]={:?}   array[j]={:?}", j, array[i], array[j]);

            array.swap(i, j);
            println!("   new array: {:?}", array);
        }
    }

    println!("output array: {:?}", array);

    // panic!("Ok");
}
<commit_msg>Better prints<commit_after>//! Selection sort algorithm.
//!
//! The `selection` module contains the simple sorting algorithm "Selection Sort".
//!
//! Source: https://en.wikipedia.org/wiki/Selection_sort

use std::fmt::Debug;

/// Simple sort: selection sort.
///
/// # Details
///
/// Selection sort is one of the simplest sorting algorithm. The list to sort is split into two
/// sections; the first with the sorted element (starting empty) and the second with the remaining
/// element (starting full). At every iteration, the smallest element in the remaining list is
/// found and placed at the end of the sorted list.
///
/// This function takes an immutable reference vector of any type and returns a vector of `usize`
/// of the same length containing the indices of the initial vector sorted.
///
/// # Scaling
///
/// Selection sort in scale as O(N^2) since for all elements to sort, the algorithm will compare it
/// with every (remaining) elements.
///
/// Insertion sort is still useful as it is quite simple.
///
/// # Optimizations
///
/// None
///
/// # Notes
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let mut data: Vec<i32> = vec![4, 2, 3, 1, 5];
/// sorting::simplesorts::selection::sort(&mut data);
/// assert_eq!(vec![1, 2, 3, 4, 5], data);
/// ```
///
pub fn sort<T: Ord + Debug>(array: &mut Vec<T>) {
    println!("input array:  {:?}", array);

    if !array.is_empty() {
        // Let's loop over the input array, skipping last value (important as we want to get a
        // slice of the following values).
        let n = array.len();
        for i in 0..n-1 {
            println!("    i: {:?}", i);

            // Find index of the minimum value in the slice of values following the i^th element.
            let j = {
                let int_slice = &array[i+1..];
                println!("        array:        {:?}", array);
                println!("        int_slice:    {:?}", int_slice);
                // k now holds the index (of "array") of the minimum element of "int_slice", or the
                // value "i" of the current element of "array" (which should be the less than
                // all elements of "int_slice").
                // "k" is a tuple containing the smallest element of "int_slice" and its index.
                //     k.0: Index of "int_slice" of its smallest value.
                //     k.1: Smallest value of "int_slice".
                let k = int_slice.iter().enumerate().fold(
                    (0, int_slice.first().unwrap()), |acc, item| {
                        if acc.1 > item.1 { item } else { acc }
                });

                // Return from the block the smallest element between the one at index "i" of
                // the "array" and the smallest one from the "int_slice" array.
                // NOTE: Since "k" worked on the subarray "int_slice", it's first element is the
                //       i^th element of "array". If "k" is actually smaller than "array[i]", we
                //       need to adapt the index as stored in "k.0".
                if k.1 < &array[i] { i + k.0 + 1 } else { i }
            };
            println!("            j: {:?}   array[i]={:?}   array[j]={:?}", j, array[i], array[j]);

            array.swap(i, j);
            println!("        new array:    {:?}", array);
        }
    }

    println!("output array: {:?}", array);

    // panic!("Ok");
}
<|endoftext|>


<commit_before>use std::io::IoResult;
use std::collections::hashmap::HashMap;

use super::{get_file_reader, get_file_writer};

pub fn generate(list: Path, module: Path) -> IoResult<()> {
    let mut reader = get_file_reader(list);
    let mut writer = get_file_writer(module);

    try!(writer.write(
b"// This automatically generated file is included in response.rs.
use std::path::BytesContainer;

use http::headers::content_type::MediaType;

pub fn get_content_type(path: &Path) -> Option<MediaType> {
    let path_str = path.container_as_str().unwrap();
    let ext_pos = regex!(\".[a-z0-9]+$\").find(path_str);
    let mut ext;
    match ext_pos {
        Some((start, _)) => {
            ext = path_str.as_slice().slice_from(start);
        },
        None => return None
    }

    match ext {
"   ));

    /* Generated snippets will look like:
    "json" => Some(MediaType {
        type_: "application".to_str(),
        subtype: "json".to_str(),
        parameters: vec![]
    }),
    */

    let mut byter = reader.bytes();
    // avoid duplicates
    let mut seen = HashMap::new();
    'read: loop {
        let mut ext = vec![];
        let mut type_ = vec![];
        let mut subtype = vec![];
        loop {
            match byter.next() {
                Some(Ok(b' ')) => break,
                Some(Ok(c)) => ext.push(c),
                Some(Err(e)) => return Err(e),
                None => break 'read
            }
        }
        loop {
            match byter.next() {
                Some(Ok(b' ')) => break,
                Some(Ok(c)) => type_.push(c),
                Some(Err(e)) => return Err(e),
                None => break 'read
            }
        }
        loop {
            match byter.next() {
                Some(Ok(b'\n')) => break,
                Some(Ok(c)) => subtype.push(c),
                Some(Err(e)) => return Err(e),
                None => break 'read
            }
        }

        if !seen.contains_key(&ext) {

            try!(writer.write(
b"        \""));
            try!(writer.write(ext.as_slice()));
            try!(writer.write(b"\" => Some(MediaType {
        type_: \""));
            try!(writer.write(type_.as_slice()));
            try!(writer.write(b"\".to_str(),
        subtype: \""));
            try!(writer.write(subtype.as_slice()));
            try!(writer.write(b"\".to_str(),
        parameters: vec![]
        }),
"           ));

            seen.insert(ext, true);
        }
    }

    writer.write(
b"        _ => None
    }
}
"   )
}
<commit_msg>(refactor) Cleaned mime generation.<commit_after>use std::io::IoResult;
use std::collections::hashmap::HashMap;
use std::str::from_utf8;

use super::{get_file_reader, get_file_writer};

pub fn generate(list: Path, module: Path) -> IoResult<()> {
    let mut reader = get_file_reader(list);
    let mut writer = get_file_writer(module);

    try!(writer.write(
b"// This automatically generated file is included in response.rs.
use std::path::BytesContainer;

use http::headers::content_type::MediaType;

pub fn get_content_type(path: &Path) -> Option<MediaType> {
    let path_str = path.container_as_str().unwrap();
    let ext_pos = regex!(\".[a-z0-9]+$\").find(path_str);
    let mut ext;
    match ext_pos {
        Some((start, _)) => {
            ext = path_str.as_slice().slice_from(start);
        },
        None => return None
    }

    match ext {
"   ));

    /* Generated snippets will look like:
    "json" => Some(MediaType {
        type_: "application".to_str(),
        subtype: "json".to_str(),
        parameters: vec![]
    }),
    */

    let mut byter = reader.bytes();
    // avoid duplicates
    let mut seen = HashMap::new();
    'read: loop {
        let mut ext = vec![];
        let mut type_ = vec![];
        let mut subtype = vec![];
        loop {
            match byter.next() {
                Some(Ok(b' ')) => break,
                Some(Ok(c)) => ext.push(c),
                Some(Err(e)) => return Err(e),
                None => break 'read
            }
        }
        loop {
            match byter.next() {
                Some(Ok(b' ')) => break,
                Some(Ok(c)) => type_.push(c),
                Some(Err(e)) => return Err(e),
                None => break 'read
            }
        }
        loop {
            match byter.next() {
                Some(Ok(b'\n')) => break,
                Some(Ok(c)) => subtype.push(c),
                Some(Err(e)) => return Err(e),
                None => break 'read
            }
        }

        if !seen.contains_key(&ext) {

            try!(write!(writer,
"    \"{}\" => Some(MediaType {{
        type_: \"{}\".to_str(),
        subtype: \"{}\".to_str(),
        parameters: vec![]
    }}),\n", from_utf8(ext.as_slice()).unwrap(),
             from_utf8(type_.as_slice()).unwrap(),
             from_utf8(subtype.as_slice()).unwrap()));

            seen.insert(ext, true);
        }
    }

    writer.write(b"        _ => None\n    }\n}\n")
}
<|endoftext|>


<commit_before>#[macro_use(run_test)]
extern crate interpreter;

#[test]
fn simple_assignment() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = 1;
            b = true;
        "
    );
}

#[test]
fn constant_arithmetic() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = (-(1+1)*(2/(3-8)))%0.3; // 0.8
        "
    );
}

#[test]
fn comparisons() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = 1 < 1;
            b = 1 <= 1;
            c = 1 > 1;
            d = 1 >= 1;
            e = 1 == 2;
            f = 1 != 2;
            g = true == false;
            h = true != false;

        "
    );
}

#[test]
fn boolean_arithmetic() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = true || !true;
            b = true && !true;
            c = true ^^ !true;
        "
    );
}

#[test]
fn reassign() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = 1;
            a = 2;
        "
    );
}

#[test]
fn global_ref() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = 1;
            b = a + 1;
        "
    );
}

#[test]
fn conditional() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = 2;
            b = 3;
            c = (a if true else a)
                if a + b < a * b
                else (a if false else b);
            d = true if true else true;
        "
    );
}

#[test]
fn block() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = { true };
            b = { 1; 2; 3 };
            c = { 1; { 2; 3 } };
        "
    );
}

#[test]
fn block_assignment() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = {
                b = true;
                5 if b else 6;
                b = !b;
                5 if b else 6;
            };
        "
    );
}

#[test]
fn function_def() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a x, y, z, w {
                x+y*z-w;
            }
            b = a[y=2, z=3, w=4, x=1];
        "
    );
}

#[test]
fn closure() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = \x { x+5 };
            b = a;
            c = b[x=5];
        "
    );
}

#[test]
fn default_args() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a x=2, y { x+y }
            b = a[y=5];
        ");
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a x, y=2 { x+y }
            b = a[x=5];
            c = a(5);
        ");
}

#[test]
fn factorial() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fact n {
                n*fact[n -= 1] if n > 1 else 1;
            }
            x = fact(10);
        ");
}

#[test]
fn fib() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fib n {
                fib[n -= 1] + fib[n -= 2] if n > 2 else 1;
            }
            x = fib(10);
        ");
}

#[test]
fn closure_default_args() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            foo bar=\y{y*2} { bar }
            a = foo()(2);
        ");
}

#[test]
fn unused_function() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fn x {
                x*5;
            }
        ");
}

// not passing because the testing macro doesn't define any intrinsics
#[test]
fn intrinsics() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            x = 1.5;
            y = sin(x) + cos(x) + sqrt(x) + log(x) + log2(x) + floor(x) + exp(x);
        ");
}

#[test]
fn closure_capture() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            x = 5;
            y = \{x+5};
            z = {
                x = true;
                y();
            };
        ");
}

#[test]
fn return_closure_capture() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fn x {
                z = 5;
                \w=x{w+z};
            }
            y = fn(5);
            z = fn(6);
            x = y() + z(); // x == 21
        ");
}

// it's currently unclear whether this is okay or not.
// if it's an easy fix it'll work soon.
#[test]
fn use_funtion_before_def() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fn1 {
                fn2()
            }
            fn2 {
                42
            }
            x = fn1();
        ");
}

#[test]
fn pass_function() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fiver fn {
                fn(5)
            }

            square x {
                x*x
            }

            x = fiver(square);
        ");
}

#[test]
fn pass_closure() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fiver fn {
                fn(5)
            }

            x = fiver(\x { x*x });
        ");
}

#[test]
fn return_function() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            passthru x {
                x
            }

            squarer {
                \x { x*x }
            }

            square = passthru(squarer());
            x = square(5);
            y = square(6);
        ");
}

#[test]
fn return_closure() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            squarer {
                \x { x*x }
            }

            square = squarer();
            x = square(5);
            y = square(6);
        ");
}

#[test]
fn argument_ordering() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fn1 x, y {
                x if y else -x;
            }
            fn2 y, x {
                x if y else -x;
            }
            fn3 = \x, y {
                x if y else -x;
            };
            fn4 = \y, x {
                x if y else -x;
            };
            a = fn1[x=1, y=true];
            b = fn1(1, true);
            c = fn2[y=true, x=1];
            d = fn2(true, 1);
            e = fn3[x=1, y=true];
            f = fn3(1, true);
            g = fn4[y=true, x=1];
            h = fn4(true, 1);
        ");
}
<commit_msg>Failing test that will work once closure capture is implemented properly<commit_after>#[macro_use(run_test)]
extern crate interpreter;

#[test]
fn simple_assignment() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = 1;
            b = true;
        "
    );
}

#[test]
fn constant_arithmetic() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = (-(1+1)*(2/(3-8)))%0.3; // 0.8
        "
    );
}

#[test]
fn comparisons() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = 1 < 1;
            b = 1 <= 1;
            c = 1 > 1;
            d = 1 >= 1;
            e = 1 == 2;
            f = 1 != 2;
            g = true == false;
            h = true != false;

        "
    );
}

#[test]
fn boolean_arithmetic() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = true || !true;
            b = true && !true;
            c = true ^^ !true;
        "
    );
}

#[test]
fn reassign() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = 1;
            a = 2;
        "
    );
}

#[test]
fn global_ref() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = 1;
            b = a + 1;
        "
    );
}

#[test]
fn conditional() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = 2;
            b = 3;
            c = (a if true else a)
                if a + b < a * b
                else (a if false else b);
            d = true if true else true;
        "
    );
}

#[test]
fn block() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = { true };
            b = { 1; 2; 3 };
            c = { 1; { 2; 3 } };
        "
    );
}

#[test]
fn block_assignment() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = {
                b = true;
                5 if b else 6;
                b = !b;
                5 if b else 6;
            };
        "
    );
}

#[test]
fn function_def() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a x, y, z, w {
                x+y*z-w;
            }
            b = a[y=2, z=3, w=4, x=1];
        "
    );
}

#[test]
fn closure() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a = \x { x+5 };
            b = a;
            c = b[x=5];
        "
    );
}

#[test]
fn default_args() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a x=2, y { x+y }
            b = a[y=5];
        ");
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            a x, y=2 { x+y }
            b = a[x=5];
            c = a(5);
        ");
}

#[test]
fn factorial() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fact n {
                n*fact[n -= 1] if n > 1 else 1;
            }
            x = fact(10);
        ");
}

#[test]
fn fib() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fib n {
                fib[n -= 1] + fib[n -= 2] if n > 2 else 1;
            }
            x = fib(10);
        ");
}

#[test]
fn closure_default_args() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            foo bar=\y{y*2} { bar }
            a = foo()(2);
        ");
}

#[test]
fn unused_function() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fn x {
                x*5;
            }
        ");
}

// not passing because the testing macro doesn't define any intrinsics
#[test]
fn intrinsics() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            x = 1.5;
            y = sin(x) + cos(x) + sqrt(x) + log(x) + log2(x) + floor(x) + exp(x);
        ");
}

#[test]
fn closure_capture() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            x = 5;
            y = \{x+5};
            z = {
                x = true;
                y();
            };
        ");
}

#[test]
fn return_closure_capture() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fn x {
                z = 5;
                \w=x{w+z};
            }
            y = fn(5);
            z = fn(6);
            x = y() + z(); // x == 21
        ");
}

// it's currently unclear whether this is okay or not.
// if it's an easy fix it'll work soon.
#[test]
fn use_funtion_before_def() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fn1 {
                fn2()
            }
            fn2 {
                42
            }
            x = fn1();
        ");
}

#[test]
fn pass_function() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fiver fn {
                fn(5)
            }

            square x {
                x*x
            }

            x = fiver(square);
        ");
}

#[test]
fn pass_closure() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fiver fn {
                fn(5)
            }

            x = fiver(\x { x*x });
        ");
}

#[test]
fn return_function() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            passthru x {
                x
            }

            squarer {
                \x { x*x }
            }

            square = passthru(squarer());
            x = square(5);
            y = square(6);
        ");
}

#[test]
fn return_closure() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            squarer {
                \x { x*x }
            }

            square = squarer();
            x = square(5);
            y = square(6);
        ");
}

#[test]
fn argument_ordering() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fn1 x, y {
                x if y else -x;
            }
            fn2 y, x {
                x if y else -x;
            }
            fn3 = \x, y {
                x if y else -x;
            };
            fn4 = \y, x {
                x if y else -x;
            };
            a = fn1[x=1, y=true];
            b = fn1(1, true);
            c = fn2[y=true, x=1];
            d = fn2(true, 1);
            e = fn3[x=1, y=true];
            f = fn3(1, true);
            g = fn4[y=true, x=1];
            h = fn4(true, 1);
        ");
}

#[test]
fn complex_closure_capture() {
    run_test!(
        should_pass(lex, parse, typecheck, codegen)
        => r"
            fn x {
                y = 2^x if x < 1 else x^2;
                \n { y%n };
            }
            x = fn(3)(2);
        ");
}
<|endoftext|>


<commit_before>extern crate mocktopus;

mod mocking_fns;
mod mocking_methods;
mod mocking_trait_defaults;
mod mocking_traits;

use mocktopus::macros::*;
use mocktopus::mocking::*;
use mocktopus::mocking_utils::*;
use std::fmt::Display;

mod mock_safe {
    use super::*;

    #[mockable]
    pub fn no_args_returns_str() -> &'static str {
        "not mocked"
    }

    #[test]
    fn when_not_mocked_then_returns_not_mocked() {
        assert_eq!("not mocked", no_args_returns_str());
    }

    #[test]
    fn when_mocked_then_returns_mocked() {
        no_args_returns_str.mock_safe(|| MockResult::Return("mocked"));

        assert_eq!("mocked", no_args_returns_str());
    }
}

mod mocks_do_not_leak_between_tests {
    use super::*;

    #[mockable]
    pub fn no_args_returns_str() -> &'static str {
        "not mocked"
    }

    macro_rules! generate_tests {
        ($($fn_name:ident),+) => {
            $(
                #[test]
                fn $fn_name() {
                    assert_eq!("not mocked", no_args_returns_str(), "function was mocked before mocking");

                    unsafe {
                        no_args_returns_str.mock_raw(|| MockResult::Return(stringify!($fn_name)));
                    }

                    assert_eq!(stringify!($fn_name), no_args_returns_str(), "mocking failed");
                }
            )+
        }
    }

    generate_tests!(t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19);
    generate_tests!(t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32, t33, t34, t35, t36, t37, t38, t39);
    generate_tests!(t40, t41, t42, t43, t44, t45, t46, t47, t48, t49, t50, t51, t52, t53, t54, t55, t56, t57, t58, t59);
    generate_tests!(t60, t61, t62, t63, t64, t65, t66, t67, t68, t69, t70, t71, t72, t73, t74, t75, t76, t77, t78, t79);
    generate_tests!(t80, t81, t82, t83, t84, t85, t86, t87, t88, t89, t90, t91, t92, t93, t94, t95, t96, t97, t98, t99);
}

mod panicking_inside_mock_is_safe {
    use super::*;

    #[mockable]
    fn function(_has_drop: String) {

    }

    #[test]
    #[should_panic]
    fn uninitialised_string_is_not_dropped() {
        function.mock_safe(|_| panic!("inside mock"));

        function("initialised".to_string());
    }
}

mod mocking_generic_over_a_type_with_lifetime_mocks_all_lifetime_variants {
    use super::*;
    use std::fmt::Display;

    #[mockable]
    fn function<T: Display>(generic: T) -> String {
        format!("not mocked {}", generic)
    }

    static STATIC_CHAR: char = 'S';

    #[test]
    fn all_lifetime_variants_get_mocked() {
        unsafe {
            function::<&char>.mock_raw(|c| MockResult::Return(format!("mocked {}", c)));
        }
        let local_char = 'L';

        assert_eq!("mocked L", function(&local_char));
        assert_eq!("mocked S", function(&STATIC_CHAR));
        assert_eq!("not mocked 3", function(&3));
    }
}

mod mocking_generic_over_a_reference_does_not_mock_opposite_mutability_variant {
    use super::*;
    use std::fmt::Display;

    #[mockable]
    fn function<T: Display>(generic: T) -> String {
        format!("not mocked {}", generic)
    }

    #[test]
    fn mocking_for_ref_does_not_mock_for_mut_ref() {
        unsafe {
            function::<&char>.mock_raw(|c| MockResult::Return(format!("mocked {}", c)));
        }

        assert_eq!("mocked R", function(&'R'));
        assert_eq!("not mocked M", function(&mut 'M'));
    }

    #[test]
    fn mocking_for_mut_ref_does_not_mock_for_ref() {
        unsafe {
            function::<&mut char>.mock_raw(|c| MockResult::Return(format!("mocked {}", c)));
        }

        assert_eq!("not mocked R", function(&'R'));
        assert_eq!("mocked M", function(&mut 'M'));
    }
}

mod mocking_trait_default_for_struct_does_not_mock_same_default_for_another_struct {
    use super::*;

    #[mockable]
    trait Trait {
        fn function() -> &'static str {
            "not mocked"
        }
    }

    struct Struct1;

    impl Trait for Struct1 {

    }

    struct Struct2;

    impl Trait for Struct2 {

    }

    #[test]
    fn when_not_mocked_then_both_run_normally() {
        assert_eq!("not mocked", Struct1::function());
        assert_eq!("not mocked", Struct2::function());
    }

    #[test]
    fn when_mocked_for_one_then_runs_mock_for_it_and_runs_normally_for_other() {
        unsafe {
            Struct1::function.mock_raw(|| MockResult::Return("mocked"))
        }

        assert_eq!("mocked", Struct1::function());
        assert_eq!("not mocked", Struct2::function());
    }
}

mod mock_closures_can_mutate_their_state {
    use super::*;

    #[mockable]
    fn function() -> &'static str {
        "not mocked"
    }

    #[test]
    fn when_not_mocked_then_runs_normally() {
        assert_eq!("not mocked", function());
    }

    #[test]
    fn when_mocked_then_runs_mocks_with_state() {
        let mut x = 0;
        function.mock_safe(move || {
            x += 1;
            match x {
                1 => MockResult::Return("first mock"),
                _ => MockResult::Return("other mock"),
            }
        });

        assert_eq!("first mock", function());
        assert_eq!("other mock", function());
    }
}

mod calling_mocked_function_inside_mock_closure {
    use super::*;

    #[mockable]
    fn mockable_1() -> String {
        "not mocked 1".to_string()
    }

    #[mockable]
    fn mockable_2() -> String {
        "not mocked 2".to_string()
    }

    fn not_mockable() -> String {
        "not mockable".to_string()
    }

    #[test]
    fn when_calling_itself_then_does_not_run_mock() {
        let mut first_call = true;
        mockable_1.mock_safe(move || {
            match first_call {
                true => {
                    first_call = false;
                    MockResult::Return(format!("mocked 1 {}", mockable_1()))
                },
                false => panic!("Mock called second time"),
            }
        });

        assert_eq!("mocked 1 not mocked 1", mockable_1());
    }

    #[test]
    fn when_calling_not_mocked_function_then_runs_it_normally() {
        mockable_1.mock_safe(|| MockResult::Return(format!("mocked 1 {}", mockable_2())));

        assert_eq!("mocked 1 not mocked 2", mockable_1());
    }

    #[test]
    fn when_calling_mocked_function_then_runs_its_mock() {
        mockable_1.mock_safe(|| MockResult::Return(format!("mocked 1 {}", mockable_2())));
        mockable_2.mock_safe(|| MockResult::Return("mocked 2".to_string()));

        assert_eq!("mocked 1 mocked 2", mockable_1());
    }

    #[test]
    fn when_calling_not_mockable_function_then_runs_it_normally() {
        mockable_1.mock_safe(|| MockResult::Return(format!("mocked 1 {}", not_mockable())));

        assert_eq!("mocked 1 not mockable", mockable_1());
    }
}

mod creating_mock_inside_mock_closure {
    use super::*;

    #[mockable]
    fn mockable_1() -> String {
        "not mocked 1".to_string()
    }

    #[mockable]
    fn mockable_2() -> String {
        "not mocked 2".to_string()
    }

    #[test]
    fn when_creating_mock_of_itself_then_registers_mock() {
        mockable_1.mock_safe(|| {
            mockable_1.mock_safe(|| MockResult::Return("mocked 1B".to_string()));
            MockResult::Return("mocked 1A".to_string())
        });

        assert_eq!("mocked 1A", mockable_1());
        assert_eq!("mocked 1B", mockable_1());
    }

    #[test]
    fn when_creating_mock_of_itself_and_calling_itself_then_runs_new_mock() {
        mockable_1.mock_safe(|| {
            mockable_1.mock_safe(|| MockResult::Return("mocked 1B".to_string()));
            MockResult::Return(format!("mocked 1A {}", mockable_1()))
        });

        assert_eq!("mocked 1A mocked 1B", mockable_1());
    }

    #[test]
    fn when_creating_mock_of_other_function_then_registers_mock() {
        mockable_1.mock_safe(|| {
            mockable_2.mock_safe(|| MockResult::Return("mocked 2".to_string()));
            MockResult::Return("mocked 1".to_string())
        });

        assert_eq!("not mocked 2", mockable_2());
        assert_eq!("mocked 1", mockable_1());
        assert_eq!("mocked 2", mockable_2());
    }

    #[test]
    fn when_creating_mock_of_other_function_and_calling_it_then_runs_new_mock() {
        mockable_1.mock_safe(|| {
            mockable_2.mock_safe(|| MockResult::Return("mocked 2".to_string()));
            MockResult::Return(format!("mocked 1 {}", mockable_2()))
        });

        assert_eq!("mocked 1 mocked 2", mockable_1());
    }
}
<commit_msg>Test for clear_mocks()<commit_after>extern crate mocktopus;

mod mocking_fns;
mod mocking_methods;
mod mocking_trait_defaults;
mod mocking_traits;

use mocktopus::macros::*;
use mocktopus::mocking::*;
use mocktopus::mocking_utils::*;
use std::fmt::Display;

mod mock_safe {
    use super::*;

    #[mockable]
    pub fn no_args_returns_str() -> &'static str {
        "not mocked"
    }

    #[test]
    fn when_not_mocked_then_returns_not_mocked() {
        assert_eq!("not mocked", no_args_returns_str());
    }

    #[test]
    fn when_mocked_then_returns_mocked() {
        no_args_returns_str.mock_safe(|| MockResult::Return("mocked"));

        assert_eq!("mocked", no_args_returns_str());
    }
}

mod mocks_do_not_leak_between_tests {
    use super::*;

    #[mockable]
    pub fn no_args_returns_str() -> &'static str {
        "not mocked"
    }

    macro_rules! generate_tests {
        ($($fn_name:ident),+) => {
            $(
                #[test]
                fn $fn_name() {
                    assert_eq!("not mocked", no_args_returns_str(), "function was mocked before mocking");

                    unsafe {
                        no_args_returns_str.mock_raw(|| MockResult::Return(stringify!($fn_name)));
                    }

                    assert_eq!(stringify!($fn_name), no_args_returns_str(), "mocking failed");
                }
            )+
        }
    }

    generate_tests!(t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19);
    generate_tests!(t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32, t33, t34, t35, t36, t37, t38, t39);
    generate_tests!(t40, t41, t42, t43, t44, t45, t46, t47, t48, t49, t50, t51, t52, t53, t54, t55, t56, t57, t58, t59);
    generate_tests!(t60, t61, t62, t63, t64, t65, t66, t67, t68, t69, t70, t71, t72, t73, t74, t75, t76, t77, t78, t79);
    generate_tests!(t80, t81, t82, t83, t84, t85, t86, t87, t88, t89, t90, t91, t92, t93, t94, t95, t96, t97, t98, t99);
}

mod panicking_inside_mock_is_safe {
    use super::*;

    #[mockable]
    fn function(_has_drop: String) {

    }

    #[test]
    #[should_panic]
    fn uninitialised_string_is_not_dropped() {
        function.mock_safe(|_| panic!("inside mock"));

        function("initialised".to_string());
    }
}

mod mocking_generic_over_a_type_with_lifetime_mocks_all_lifetime_variants {
    use super::*;
    use std::fmt::Display;

    #[mockable]
    fn function<T: Display>(generic: T) -> String {
        format!("not mocked {}", generic)
    }

    static STATIC_CHAR: char = 'S';

    #[test]
    fn all_lifetime_variants_get_mocked() {
        unsafe {
            function::<&char>.mock_raw(|c| MockResult::Return(format!("mocked {}", c)));
        }
        let local_char = 'L';

        assert_eq!("mocked L", function(&local_char));
        assert_eq!("mocked S", function(&STATIC_CHAR));
        assert_eq!("not mocked 3", function(&3));
    }
}

mod mocking_generic_over_a_reference_does_not_mock_opposite_mutability_variant {
    use super::*;
    use std::fmt::Display;

    #[mockable]
    fn function<T: Display>(generic: T) -> String {
        format!("not mocked {}", generic)
    }

    #[test]
    fn mocking_for_ref_does_not_mock_for_mut_ref() {
        unsafe {
            function::<&char>.mock_raw(|c| MockResult::Return(format!("mocked {}", c)));
        }

        assert_eq!("mocked R", function(&'R'));
        assert_eq!("not mocked M", function(&mut 'M'));
    }

    #[test]
    fn mocking_for_mut_ref_does_not_mock_for_ref() {
        unsafe {
            function::<&mut char>.mock_raw(|c| MockResult::Return(format!("mocked {}", c)));
        }

        assert_eq!("not mocked R", function(&'R'));
        assert_eq!("mocked M", function(&mut 'M'));
    }
}

mod mocking_trait_default_for_struct_does_not_mock_same_default_for_another_struct {
    use super::*;

    #[mockable]
    trait Trait {
        fn function() -> &'static str {
            "not mocked"
        }
    }

    struct Struct1;

    impl Trait for Struct1 {

    }

    struct Struct2;

    impl Trait for Struct2 {

    }

    #[test]
    fn when_not_mocked_then_both_run_normally() {
        assert_eq!("not mocked", Struct1::function());
        assert_eq!("not mocked", Struct2::function());
    }

    #[test]
    fn when_mocked_for_one_then_runs_mock_for_it_and_runs_normally_for_other() {
        unsafe {
            Struct1::function.mock_raw(|| MockResult::Return("mocked"))
        }

        assert_eq!("mocked", Struct1::function());
        assert_eq!("not mocked", Struct2::function());
    }
}

mod mock_closures_can_mutate_their_state {
    use super::*;

    #[mockable]
    fn function() -> &'static str {
        "not mocked"
    }

    #[test]
    fn when_not_mocked_then_runs_normally() {
        assert_eq!("not mocked", function());
    }

    #[test]
    fn when_mocked_then_runs_mocks_with_state() {
        let mut x = 0;
        function.mock_safe(move || {
            x += 1;
            match x {
                1 => MockResult::Return("first mock"),
                _ => MockResult::Return("other mock"),
            }
        });

        assert_eq!("first mock", function());
        assert_eq!("other mock", function());
    }
}

mod calling_mocked_function_inside_mock_closure {
    use super::*;

    #[mockable]
    fn mockable_1() -> String {
        "not mocked 1".to_string()
    }

    #[mockable]
    fn mockable_2() -> String {
        "not mocked 2".to_string()
    }

    fn not_mockable() -> String {
        "not mockable".to_string()
    }

    #[test]
    fn when_calling_itself_then_does_not_run_mock() {
        let mut first_call = true;
        mockable_1.mock_safe(move || {
            match first_call {
                true => {
                    first_call = false;
                    MockResult::Return(format!("mocked 1 {}", mockable_1()))
                },
                false => panic!("Mock called second time"),
            }
        });

        assert_eq!("mocked 1 not mocked 1", mockable_1());
    }

    #[test]
    fn when_calling_not_mocked_function_then_runs_it_normally() {
        mockable_1.mock_safe(|| MockResult::Return(format!("mocked 1 {}", mockable_2())));

        assert_eq!("mocked 1 not mocked 2", mockable_1());
    }

    #[test]
    fn when_calling_mocked_function_then_runs_its_mock() {
        mockable_1.mock_safe(|| MockResult::Return(format!("mocked 1 {}", mockable_2())));
        mockable_2.mock_safe(|| MockResult::Return("mocked 2".to_string()));

        assert_eq!("mocked 1 mocked 2", mockable_1());
    }

    #[test]
    fn when_calling_not_mockable_function_then_runs_it_normally() {
        mockable_1.mock_safe(|| MockResult::Return(format!("mocked 1 {}", not_mockable())));

        assert_eq!("mocked 1 not mockable", mockable_1());
    }
}

mod creating_mock_inside_mock_closure {
    use super::*;

    #[mockable]
    fn mockable_1() -> String {
        "not mocked 1".to_string()
    }

    #[mockable]
    fn mockable_2() -> String {
        "not mocked 2".to_string()
    }

    #[test]
    fn when_creating_mock_of_itself_then_registers_mock() {
        mockable_1.mock_safe(|| {
            mockable_1.mock_safe(|| MockResult::Return("mocked 1B".to_string()));
            MockResult::Return("mocked 1A".to_string())
        });

        assert_eq!("mocked 1A", mockable_1());
        assert_eq!("mocked 1B", mockable_1());
    }

    #[test]
    fn when_creating_mock_of_itself_and_calling_itself_then_runs_new_mock() {
        mockable_1.mock_safe(|| {
            mockable_1.mock_safe(|| MockResult::Return("mocked 1B".to_string()));
            MockResult::Return(format!("mocked 1A {}", mockable_1()))
        });

        assert_eq!("mocked 1A mocked 1B", mockable_1());
    }

    #[test]
    fn when_creating_mock_of_other_function_then_registers_mock() {
        mockable_1.mock_safe(|| {
            mockable_2.mock_safe(|| MockResult::Return("mocked 2".to_string()));
            MockResult::Return("mocked 1".to_string())
        });

        assert_eq!("not mocked 2", mockable_2());
        assert_eq!("mocked 1", mockable_1());
        assert_eq!("mocked 2", mockable_2());
    }

    #[test]
    fn when_creating_mock_of_other_function_and_calling_it_then_runs_new_mock() {
        mockable_1.mock_safe(|| {
            mockable_2.mock_safe(|| MockResult::Return("mocked 2".to_string()));
            MockResult::Return(format!("mocked 1 {}", mockable_2()))
        });

        assert_eq!("mocked 1 mocked 2", mockable_1());
    }
}

mod clear_mocks {
    use super::*;

    #[mockable]
    fn mockable_1() -> String {
        "not mocked 1".to_string()
    }

    #[mockable]
    fn mockable_2() -> String {
        "not mocked 2".to_string()
    }

    #[test]
    fn when_clearing_mocks_original_function_operations_return() {
        mockable_1.mock_safe(|| {
            MockResult::Return("mocked 1".to_string())
        });
        mockable_2.mock_safe(|| {
            MockResult::Return("mocked 2".to_string())
        });

        assert_eq!("mocked 1", mockable_1());
        assert_eq!("mocked 2", mockable_2());

        clear_mocks();

        assert_eq!("not mocked 1", mockable_1());
        assert_eq!("not mocked 2", mockable_2());
    }
}
<|endoftext|>


<commit_before>#![allow(unused_features)]
#![feature(io)]

extern crate cbor;
extern crate quickcheck;
extern crate rand;
extern crate "rustc-serialize" as rustc_serialize;

use std::collections::HashMap;
use std::fmt::Debug;
use rand::thread_rng;
use rustc_serialize::{Decodable, Encodable};
use quickcheck::{QuickCheck, StdGen, Testable};

use cbor::{Encoder, Decoder, Cbor, CborBytes, CborTagEncode};

// A trivial logging macro. No reason to pull in `log`, which has become
// difficult to use in tests.
macro_rules! lg {
    ($($arg:tt)*) => ({
        let _ = ::std::old_io::stderr().write_str(&*format!($($arg)*));
        let _ = ::std::old_io::stderr().write_str("\n");
    });
}

fn qc_sized<A: Testable>(f: A, size: u64) {
    QuickCheck::new()
        .gen(StdGen::new(thread_rng(), size as usize))
        .tests(1_00)
        .max_tests(10_000)
        .quickcheck(f);
}

fn round_trip<T>(v: T) -> bool
        where T: Decodable + Encodable + Debug + PartialEq {
    let backv: T = decode(&encode(&v));
    assert_eq!(backv, v);
    true
}

fn encode<T: Encodable>(v: T) -> Vec<u8> {
    let mut enc = Encoder::from_memory();
    enc.encode(&[v]).unwrap();
    enc.as_bytes().to_vec()
}

fn decode<T: Decodable>(bytes: &[u8]) -> T {
    Decoder::from_bytes(bytes).decode().next().unwrap().unwrap()
}

#[allow(dead_code)]
fn readone(bytes: &[u8]) -> Cbor {
    Decoder::from_bytes(bytes).items().next().unwrap().unwrap()
}

macro_rules! round_trip_num {
    ($name:ident, $ty:ident) => (
        #[test]
        fn $name() {
            fn prop(n: $ty) -> bool { round_trip(n) }
            qc_sized(prop as fn($ty) -> bool, ::std::$ty::MAX as u64)
        }
    );
}

round_trip_num!(roundtrip_prop_usize, usize);
round_trip_num!(roundtrip_prop_u64, u64);
round_trip_num!(roundtrip_prop_u32, u32);
round_trip_num!(roundtrip_prop_u16, u16);
round_trip_num!(roundtrip_prop_u8, u8);
round_trip_num!(roundtrip_prop_isize, isize);
round_trip_num!(roundtrip_prop_i64, i64);
round_trip_num!(roundtrip_prop_i32, i32);
round_trip_num!(roundtrip_prop_i16, i16);
round_trip_num!(roundtrip_prop_i8, i8);

#[test]
fn roundtrip_prop_f32() {
    fn prop(n: f32) -> bool { round_trip(n) }
    qc_sized(prop as fn(f32) -> bool, ::std::f32::MAX_VALUE as u64 - 1)
}

#[test]
fn roundtrip_prop_f64() {
    fn prop(n: f64) -> bool { round_trip(n) }
    qc_sized(prop as fn(f64) -> bool, ::std::f64::MAX_VALUE as u64 - 1)
}

macro_rules! round_trip_any {
    ($name:ident, $ty:ty) => (
        #[test]
        fn $name() {
            fn prop(n: $ty) -> bool { round_trip(n) }
            QuickCheck::new().quickcheck(prop as fn($ty) -> bool)
        }
    );
}

round_trip_any!(roundtrip_prop_nil, ());
round_trip_any!(roundtrip_prop_bool, bool);
round_trip_any!(roundtrip_prop_tuple, (i32, u32));
round_trip_any!(roundtrip_prop_tuple_in_tuple, (i32, (u32, i32), u32));
round_trip_any!(roundtrip_prop_vec, Vec<i32>);
round_trip_any!(roundtrip_prop_vec_in_vec, Vec<Vec<i32>>);
round_trip_any!(roundtrip_prop_map, HashMap<String, i32>);
round_trip_any!(roundtrip_prop_vec_in_map, HashMap<String, Vec<i32>>);
// round_trip_any!(roundtrip_prop_map_in_map,
                // HashMap<String, HashMap<String, i32>>);

#[test]
fn roundtrip_prop_byte_string() {
    fn prop(n: Vec<u8>) -> bool { round_trip(CborBytes(n)) }
    QuickCheck::new().quickcheck(prop as fn(Vec<u8>) -> bool)
}

#[test]
fn roundtrip_enum() {
    #[derive(Debug, PartialEq, RustcDecodable, RustcEncodable)]
    enum Color { Red, Blue(String, i32), Green { s: String, n: i32 } }

    round_trip(Color::Red);
    round_trip(Color::Blue("hi".to_string(), 5));
    round_trip(Color::Green { s: "hi".to_string(), n: 5 });
}

#[test]
fn roundtrip_struct() {
    #[derive(Debug, PartialEq, RustcDecodable, RustcEncodable)]
    struct Vowels { s: String, n: u32 }

    round_trip(Vowels { s: "cwm".to_string(), n: 1 });
}

#[test]
#[should_fail]
fn invalid_map_key() {
    let mut map = HashMap::new();
    map.insert(5, 5);
    encode(map);
}

#[test]
fn roundtrip_prop_tag() {
    use rustc_serialize::{Decoder, Encoder};

    #[derive(Debug, PartialEq)]
    struct MyTag {
        num: u64,
        data: Vec<i32>,
    }
    impl Decodable for MyTag {
        fn decode<D: Decoder>(d: &mut D) -> Result<MyTag, D::Error> {
            let tag = try!(d.read_u64());
            Ok(MyTag { num: tag, data: try!(Decodable::decode(d)) })
        }
    }
    impl Encodable for MyTag {
        fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
            CborTagEncode {
                tag: self.num,
                data: &self.data,
            }.encode(e)
        }
    }
    fn prop(num: u64, data: Vec<i32>) -> bool {
        round_trip(MyTag { num: num, data: data })
    }
    QuickCheck::new().quickcheck(prop as fn(u64, Vec<i32>) -> bool)
}
<commit_msg>rustup<commit_after>#![allow(unused_features)]
#![feature(io)]

extern crate cbor;
extern crate quickcheck;
extern crate rand;
extern crate "rustc-serialize" as rustc_serialize;

use std::collections::HashMap;
use std::fmt::Debug;
use rand::thread_rng;
use rustc_serialize::{Decodable, Encodable};
use quickcheck::{QuickCheck, StdGen, Testable};

use cbor::{Encoder, Decoder, Cbor, CborBytes, CborTagEncode};

// A trivial logging macro. No reason to pull in `log`, which has become
// difficult to use in tests.
macro_rules! lg {
    ($($arg:tt)*) => ({
        let _ = ::std::old_io::stderr().write_str(&*format!($($arg)*));
        let _ = ::std::old_io::stderr().write_str("\n");
    });
}

fn qc_sized<A: Testable>(f: A, size: u64) {
    QuickCheck::new()
        .gen(StdGen::new(thread_rng(), size as usize))
        .tests(1_00)
        .max_tests(10_000)
        .quickcheck(f);
}

fn round_trip<T>(v: T) -> bool
        where T: Decodable + Encodable + Debug + PartialEq {
    let backv: T = decode(&encode(&v));
    assert_eq!(backv, v);
    true
}

fn encode<T: Encodable>(v: T) -> Vec<u8> {
    let mut enc = Encoder::from_memory();
    enc.encode(&[v]).unwrap();
    enc.as_bytes().to_vec()
}

fn decode<T: Decodable>(bytes: &[u8]) -> T {
    Decoder::from_bytes(bytes).decode().next().unwrap().unwrap()
}

#[allow(dead_code)]
fn readone(bytes: &[u8]) -> Cbor {
    Decoder::from_bytes(bytes).items().next().unwrap().unwrap()
}

macro_rules! round_trip_num {
    ($name:ident, $ty:ident) => (
        #[test]
        fn $name() {
            fn prop(n: $ty) -> bool { round_trip(n) }
            qc_sized(prop as fn($ty) -> bool, ::std::$ty::MAX as u64)
        }
    );
}

round_trip_num!(roundtrip_prop_usize, usize);
round_trip_num!(roundtrip_prop_u64, u64);
round_trip_num!(roundtrip_prop_u32, u32);
round_trip_num!(roundtrip_prop_u16, u16);
round_trip_num!(roundtrip_prop_u8, u8);
round_trip_num!(roundtrip_prop_isize, isize);
round_trip_num!(roundtrip_prop_i64, i64);
round_trip_num!(roundtrip_prop_i32, i32);
round_trip_num!(roundtrip_prop_i16, i16);
round_trip_num!(roundtrip_prop_i8, i8);

#[test]
fn roundtrip_prop_f32() {
    fn prop(n: f32) -> bool { round_trip(n) }
    qc_sized(prop as fn(f32) -> bool, ::std::f32::MAX as u64 - 1)
}

#[test]
fn roundtrip_prop_f64() {
    fn prop(n: f64) -> bool { round_trip(n) }
    qc_sized(prop as fn(f64) -> bool, ::std::f64::MAX as u64 - 1)
}

macro_rules! round_trip_any {
    ($name:ident, $ty:ty) => (
        #[test]
        fn $name() {
            fn prop(n: $ty) -> bool { round_trip(n) }
            QuickCheck::new().quickcheck(prop as fn($ty) -> bool)
        }
    );
}

round_trip_any!(roundtrip_prop_nil, ());
round_trip_any!(roundtrip_prop_bool, bool);
round_trip_any!(roundtrip_prop_tuple, (i32, u32));
round_trip_any!(roundtrip_prop_tuple_in_tuple, (i32, (u32, i32), u32));
round_trip_any!(roundtrip_prop_vec, Vec<i32>);
round_trip_any!(roundtrip_prop_vec_in_vec, Vec<Vec<i32>>);
round_trip_any!(roundtrip_prop_map, HashMap<String, i32>);
round_trip_any!(roundtrip_prop_vec_in_map, HashMap<String, Vec<i32>>);
// round_trip_any!(roundtrip_prop_map_in_map,
                // HashMap<String, HashMap<String, i32>>);

#[test]
fn roundtrip_prop_byte_string() {
    fn prop(n: Vec<u8>) -> bool { round_trip(CborBytes(n)) }
    QuickCheck::new().quickcheck(prop as fn(Vec<u8>) -> bool)
}

#[test]
fn roundtrip_enum() {
    #[derive(Debug, PartialEq, RustcDecodable, RustcEncodable)]
    enum Color { Red, Blue(String, i32), Green { s: String, n: i32 } }

    round_trip(Color::Red);
    round_trip(Color::Blue("hi".to_string(), 5));
    round_trip(Color::Green { s: "hi".to_string(), n: 5 });
}

#[test]
fn roundtrip_struct() {
    #[derive(Debug, PartialEq, RustcDecodable, RustcEncodable)]
    struct Vowels { s: String, n: u32 }

    round_trip(Vowels { s: "cwm".to_string(), n: 1 });
}

#[test]
#[should_fail]
fn invalid_map_key() {
    let mut map = HashMap::new();
    map.insert(5, 5);
    encode(map);
}

#[test]
fn roundtrip_prop_tag() {
    use rustc_serialize::{Decoder, Encoder};

    #[derive(Debug, PartialEq)]
    struct MyTag {
        num: u64,
        data: Vec<i32>,
    }
    impl Decodable for MyTag {
        fn decode<D: Decoder>(d: &mut D) -> Result<MyTag, D::Error> {
            let tag = try!(d.read_u64());
            Ok(MyTag { num: tag, data: try!(Decodable::decode(d)) })
        }
    }
    impl Encodable for MyTag {
        fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
            CborTagEncode {
                tag: self.num,
                data: &self.data,
            }.encode(e)
        }
    }
    fn prop(num: u64, data: Vec<i32>) -> bool {
        round_trip(MyTag { num: num, data: data })
    }
    QuickCheck::new().quickcheck(prop as fn(u64, Vec<i32>) -> bool)
}
<|endoftext|>


<commit_before>// ignore-tidy-linelength
#![deny(broken_intra_doc_links)]

pub mod char {}

/// See also [type@char]
// @has intra_link_prim_precedence/struct.MyString.html '//a/@href' 'https://doc.rust-lang.org/nightly/std/primitive.char.html'
pub struct MyString;

/// See also [char]
// @has intra_link_prim_precedence/struct.MyString2.html '//a/@href' 'https://doc.rust-lang.org/nightly/std/primitive.char.html'
pub struct MyString2;

/// See also [crate::char] and [mod@char]
// @has intra_link_prim_precedence/struct.MyString3.html '//*[@href="../intra_link_prim_precedence/char/index.html"]' 'crate::char'
// @has - '//*[@href="../intra_link_prim_precedence/char/index.html"]' 'mod@char'
pub struct MyString3;
<commit_msg>Update primitive test to match the new behavior<commit_after>// ignore-tidy-linelength
#![deny(broken_intra_doc_links)]

pub mod char {
    /// [char]
    // @has intra_link_prim_precedence/char/struct.Inner.html '//a/@href' 'https://doc.rust-lang.org/nightly/std/primitive.char.html'
    pub struct Inner;
}

/// See [prim@char]
// @has intra_link_prim_precedence/struct.MyString.html '//a/@href' 'https://doc.rust-lang.org/nightly/std/primitive.char.html'
pub struct MyString;

/// See also [crate::char] and [mod@char]
// @has intra_link_prim_precedence/struct.MyString2.html '//*[@href="../intra_link_prim_precedence/char/index.html"]' 'crate::char'
// @has - '//*[@href="../intra_link_prim_precedence/char/index.html"]' 'mod@char'
pub struct MyString2;
<|endoftext|>