<commit_before>use ndarray::*;
use ndarray_linalg::*;
use num_traits::Float;

use super::traits::*;

/// Jacobian operator using numerical-differentiation
pub struct Jacobian<'jac, A, D, TEO>
where
    A: Scalar,
    D: Dimension,
    TEO: 'jac + TimeEvolution<Scalar = A, Dim = D>,
{
    f: &'jac mut TEO,
    x: Array<A, D>,
    fx: Array<A, D>,
    alpha: A::Real,
}

pub trait LinearApprox<A, D, TEO>
where
    A: Scalar,
    D: Dimension,
    TEO: TimeEvolution<Scalar = A, Dim = D>,
{
    fn lin_approx<'jac>(
        &'jac mut self,
        x: Array<A, D>,
        alpha: A::Real,
    ) -> Jacobian<'jac, A, D, TEO>
    where
        TEO: 'jac;
}

impl<A, D, TEO> LinearApprox<A, D, TEO> for TEO
where
    A: Scalar,
    D: Dimension,
    TEO: TimeEvolution<Scalar = A, Dim = D>,
{
    fn lin_approx<'jac>(&'jac mut self, x: Array<A, D>, alpha: A::Real) -> Jacobian<'jac, A, D, TEO>
    where
        TEO: 'jac,
    {
        Jacobian::new(self, x, alpha)
    }
}

impl<'jac, A, D, TEO> Jacobian<'jac, A, D, TEO>
where
    A: Scalar,
    D: Dimension,
    TEO: TimeEvolution<Scalar = A, Dim = D>,
{
    pub fn new(f: &'jac mut TEO, x: Array<A, D>, alpha: A::Real) -> Jacobian<'jac, A, D, TEO>
    where
        TEO: 'jac,
    {
        let mut fx = x.clone();
        f.iterate(&mut fx);
        Jacobian { f, x, fx, alpha }
    }

    pub fn apply(&mut self, mut dx: Array<A, D>) -> Array<A, D> {
        self.apply_inplace(&mut dx);
        dx
    }

    pub fn apply_inplace<S>(&mut self, dx: &mut ArrayBase<S, D>)
    where
        S: DataMut<Elem = A>,
    {
        let dx_nrm = dx.norm_l2().max(self.alpha);
        let n = self.alpha / dx_nrm;
        Zip::from(&mut *dx).and(&self.x).apply(|dx, &x| {
            *dx = x + dx.mul_real(n);
        });
        let x_dx = self.f.iterate(dx);
        Zip::from(&mut *x_dx).and(&self.fx).apply(|x_dx, &fx| {
            *x_dx = (*x_dx - fx).div_real(n);
        });
    }
}

impl<'jac, A, D, TEO> Jacobian<'jac, A, D, TEO>
where
    A: Scalar,
    D: Dimension,
    TEO: TimeEvolution<Scalar = A, Dim = D>,
{
    pub fn apply_multi(&mut self, mut a: Array<A, D::Larger>) -> Array<A, D::Larger>
    where
        D::Larger: RemoveAxis + Dimension<Smaller = D>,
    {
        self.apply_multi_inplace(&mut a);
        a
    }

    pub fn apply_multi_inplace<S>(&mut self, a: &mut ArrayBase<S, D::Larger>)
    where
        S: DataMut<Elem = A>,
        D::Larger: RemoveAxis + Dimension<Smaller = D>,
    {
        let n = a.ndim();
        for mut col in a.axis_iter_mut(Axis(n - 1)) {
            self.apply_inplace(&mut col);
        }
    }
}
<commit_msg>Return mut ref in apply_inplace<commit_after>use ndarray::*;
use ndarray_linalg::*;
use num_traits::Float;

use super::traits::*;

/// Jacobian operator using numerical-differentiation
pub struct Jacobian<'jac, A, D, TEO>
where
    A: Scalar,
    D: Dimension,
    TEO: 'jac + TimeEvolution<Scalar = A, Dim = D>,
{
    f: &'jac mut TEO,
    x: Array<A, D>,
    fx: Array<A, D>,
    alpha: A::Real,
}

pub trait LinearApprox<A, D, TEO>
where
    A: Scalar,
    D: Dimension,
    TEO: TimeEvolution<Scalar = A, Dim = D>,
{
    fn lin_approx<'jac>(
        &'jac mut self,
        x: Array<A, D>,
        alpha: A::Real,
    ) -> Jacobian<'jac, A, D, TEO>
    where
        TEO: 'jac;
}

impl<A, D, TEO> LinearApprox<A, D, TEO> for TEO
where
    A: Scalar,
    D: Dimension,
    TEO: TimeEvolution<Scalar = A, Dim = D>,
{
    fn lin_approx<'jac>(&'jac mut self, x: Array<A, D>, alpha: A::Real) -> Jacobian<'jac, A, D, TEO>
    where
        TEO: 'jac,
    {
        Jacobian::new(self, x, alpha)
    }
}

impl<'jac, A, D, TEO> Jacobian<'jac, A, D, TEO>
where
    A: Scalar,
    D: Dimension,
    TEO: TimeEvolution<Scalar = A, Dim = D>,
{
    pub fn new(f: &'jac mut TEO, x: Array<A, D>, alpha: A::Real) -> Jacobian<'jac, A, D, TEO>
    where
        TEO: 'jac,
    {
        let mut fx = x.clone();
        f.iterate(&mut fx);
        Jacobian { f, x, fx, alpha }
    }

    pub fn apply(&mut self, mut dx: Array<A, D>) -> Array<A, D> {
        self.apply_inplace(&mut dx);
        dx
    }

    pub fn apply_inplace<'a, S>(&mut self, dx: &'a mut ArrayBase<S, D>) -> &'a mut ArrayBase<S, D>
    where
        S: DataMut<Elem = A>,
    {
        let dx_nrm = dx.norm_l2().max(self.alpha);
        let n = self.alpha / dx_nrm;
        Zip::from(&mut *dx).and(&self.x).apply(|dx, &x| {
            *dx = x + dx.mul_real(n);
        });
        let x_dx = self.f.iterate(dx);
        Zip::from(&mut *x_dx).and(&self.fx).apply(|x_dx, &fx| {
            *x_dx = (*x_dx - fx).div_real(n);
        });
        x_dx
    }
}

impl<'jac, A, D, TEO> Jacobian<'jac, A, D, TEO>
where
    A: Scalar,
    D: Dimension,
    TEO: TimeEvolution<Scalar = A, Dim = D>,
{
    pub fn apply_multi(&mut self, mut a: Array<A, D::Larger>) -> Array<A, D::Larger>
    where
        D::Larger: RemoveAxis + Dimension<Smaller = D>,
    {
        self.apply_multi_inplace(&mut a);
        a
    }

    pub fn apply_multi_inplace<'a, S>(
        &mut self,
        a: &'a mut ArrayBase<S, D::Larger>,
    ) -> &'a mut ArrayBase<S, D::Larger>
    where
        S: DataMut<Elem = A>,
        D::Larger: RemoveAxis + Dimension<Smaller = D>,
    {
        let n = a.ndim();
        for mut col in a.axis_iter_mut(Axis(n - 1)) {
            self.apply_inplace(&mut col);
        }
        a
    }
}
<|endoftext|>


<commit_before>extern crate curl;
extern crate rustc_serialize;

use std::collections::HashMap;
use std::fmt;
use std::fs::{self, File};
use std::io::prelude::*;
use std::io::{self, Cursor};
use std::path::Path;
use std::result;

use curl::http;
use curl::http::handle::Method::{Put, Get, Delete};
use curl::http::handle::{Method, Request};
use rustc_serialize::json;

pub struct Registry {
    host: String,
    token: Option<String>,
    handle: http::Handle,
}

pub type Result<T> = result::Result<T, Error>;

#[derive(PartialEq, Clone, Copy)]
pub enum Auth {
    Authorized,
    Unauthorized
}

pub enum Error {
    Curl(curl::ErrCode),
    NotOkResponse(http::Response),
    NonUtf8Body,
    Api(Vec<String>),
    Unauthorized,
    TokenMissing,
    Io(io::Error),
}

#[derive(RustcDecodable)]
pub struct Crate {
    pub name: String,
    pub description: Option<String>,
    pub max_version: String
}

#[derive(RustcEncodable)]
pub struct NewCrate {
    pub name: String,
    pub vers: String,
    pub deps: Vec<NewCrateDependency>,
    pub features: HashMap<String, Vec<String>>,
    pub authors: Vec<String>,
    pub description: Option<String>,
    pub documentation: Option<String>,
    pub homepage: Option<String>,
    pub readme: Option<String>,
    pub keywords: Vec<String>,
    pub license: Option<String>,
    pub license_file: Option<String>,
    pub repository: Option<String>,
}

#[derive(RustcEncodable)]
pub struct NewCrateDependency {
    pub optional: bool,
    pub default_features: bool,
    pub name: String,
    pub features: Vec<String>,
    pub version_req: String,
    pub target: Option<String>,
    pub kind: String,
}

#[derive(RustcDecodable)]
pub struct User {
    pub id: u32,
    pub login: String,
    pub avatar: String,
    pub email: Option<String>,
    pub name: Option<String>,
}

#[derive(RustcDecodable)] struct R { ok: bool }
#[derive(RustcDecodable)] struct ApiErrorList { errors: Vec<ApiError> }
#[derive(RustcDecodable)] struct ApiError { detail: String }
#[derive(RustcEncodable)] struct OwnersReq<'a> { users: &'a [&'a str] }
#[derive(RustcDecodable)] struct Users { users: Vec<User> }
#[derive(RustcDecodable)] struct Crates { crates: Vec<Crate> }

impl Registry {
    pub fn new(host: String, token: Option<String>) -> Registry {
        Registry::new_handle(host, token, http::Handle::new())
    }

    pub fn new_handle(host: String, token: Option<String>,
                      handle: http::Handle) -> Registry {
        Registry {
            host: host,
            token: token,
            handle: handle,
        }
    }

    pub fn add_owners(&mut self, krate: &str, owners: &[&str]) -> Result<()> {
        let body = json::encode(&OwnersReq { users: owners }).unwrap();
        let body = try!(self.put(format!("/crates/{}/owners", krate),
                                 body.as_bytes()));
        assert!(json::decode::<R>(&body).unwrap().ok);
        Ok(())
    }

    pub fn remove_owners(&mut self, krate: &str, owners: &[&str]) -> Result<()> {
        let body = json::encode(&OwnersReq { users: owners }).unwrap();
        let body = try!(self.delete(format!("/crates/{}/owners", krate),
                                    Some(body.as_bytes())));
        assert!(json::decode::<R>(&body).unwrap().ok);
        Ok(())
    }

    pub fn list_owners(&mut self, krate: &str) -> Result<Vec<User>> {
        let body = try!(self.get(format!("/crates/{}/owners", krate)));
        Ok(json::decode::<Users>(&body).unwrap().users)
    }

    pub fn publish(&mut self, krate: &NewCrate, tarball: &Path) -> Result<()> {
        let json = json::encode(krate).unwrap();
        // Prepare the body. The format of the upload request is:
        //
        //      <le u32 of json>
        //      <json request> (metadata for the package)
        //      <le u32 of tarball>
        //      <source tarball>
        let stat = try!(fs::metadata(tarball).map_err(Error::Io));
        let header = {
            let mut w = Vec::new();
            w.extend([
                (json.len() >>  0) as u8,
                (json.len() >>  8) as u8,
                (json.len() >> 16) as u8,
                (json.len() >> 24) as u8,
            ].iter().map(|x| *x));
            w.extend(json.as_bytes().iter().map(|x| *x));
            w.extend([
                (stat.len() >>  0) as u8,
                (stat.len() >>  8) as u8,
                (stat.len() >> 16) as u8,
                (stat.len() >> 24) as u8,
            ].iter().map(|x| *x));
            w
        };
        let tarball = try!(File::open(tarball).map_err(Error::Io));
        let size = stat.len() as usize + header.len();
        let mut body = Cursor::new(header).chain(tarball);

        let url = format!("{}/api/v1/crates/new", self.host);

        let token = match self.token.as_ref() {
            Some(s) => s,
            None => return Err(Error::TokenMissing),
        };
        let request = self.handle.put(url, &mut body)
            .content_length(size)
            .header("Accept", "application/json")
            .header("Authorization", &token);
        let response = handle(request.exec());
        let _body = try!(response);
        Ok(())
    }

    pub fn search(&mut self, query: &str) -> Result<Vec<Crate>> {
        let body = try!(self.req(format!("/crates?q={}", query), None, Get,
                                 Auth::Unauthorized));

        Ok(json::decode::<Crates>(&body).unwrap().crates)
    }

    pub fn yank(&mut self, krate: &str, version: &str) -> Result<()> {
        let body = try!(self.delete(format!("/crates/{}/{}/yank", krate, version),
                                    None));
        assert!(json::decode::<R>(&body).unwrap().ok);
        Ok(())
    }

    pub fn unyank(&mut self, krate: &str, version: &str) -> Result<()> {
        let body = try!(self.put(format!("/crates/{}/{}/unyank", krate, version),
                                 &[]));
        assert!(json::decode::<R>(&body).unwrap().ok);
        Ok(())
    }

    fn put(&mut self, path: String, b: &[u8]) -> Result<String> {
        self.req(path, Some(b), Put, Auth::Authorized)
    }

    fn get(&mut self, path: String) -> Result<String> {
        self.req(path, None, Get, Auth::Authorized)
    }

    fn delete(&mut self, path: String, b: Option<&[u8]>) -> Result<String> {
        self.req(path, b, Delete, Auth::Authorized)
    }

    fn req(&mut self, path: String, body: Option<&[u8]>,
           method: Method, authorized: Auth) -> Result<String> {
        let mut req = Request::new(&mut self.handle, method)
                              .uri(format!("{}/api/v1{}", self.host, path))
                              .header("Accept", "application/json")
                              .content_type("application/json");

        if authorized == Auth::Authorized {
            let token = match self.token.as_ref() {
                Some(s) => s,
                None => return Err(Error::TokenMissing),
            };
            req = req.header("Authorization", &token);
        }
        match body {
            Some(b) => req = req.body(b),
            None => {}
        }
        handle(req.exec())
    }
}

fn handle(response: result::Result<http::Response, curl::ErrCode>)
          -> Result<String> {
    let response = try!(response.map_err(Error::Curl));
    match response.get_code() {
        0 => {} // file upload url sometimes
        200 => {}
        403 => return Err(Error::Unauthorized),
        _ => return Err(Error::NotOkResponse(response))
    }

    let body = match String::from_utf8(response.move_body()) {
        Ok(body) => body,
        Err(..) => return Err(Error::NonUtf8Body),
    };
    match json::decode::<ApiErrorList>(&body) {
        Ok(errors) => {
            return Err(Error::Api(errors.errors.into_iter().map(|s| s.detail)
                                        .collect()))
        }
        Err(..) => {}
    }
    Ok(body)
}

impl fmt::Display for Error {
    #[allow(deprecated)] // connect => join in 1.3
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::NonUtf8Body => write!(f, "response body was not utf-8"),
            Error::Curl(ref err) => write!(f, "http error: {}", err),
            Error::NotOkResponse(ref resp) => {
                write!(f, "failed to get a 200 OK response: {}", resp)
            }
            Error::Api(ref errs) => {
                write!(f, "api errors: {}", errs.connect(", "))
            }
            Error::Unauthorized => write!(f, "unauthorized API access"),
            Error::TokenMissing => write!(f, "no upload token found, please run `cargo login`"),
            Error::Io(ref e) => write!(f, "io error: {}", e),
        }
    }
}
<commit_msg>add missing Option to avatar<commit_after>extern crate curl;
extern crate rustc_serialize;

use std::collections::HashMap;
use std::fmt;
use std::fs::{self, File};
use std::io::prelude::*;
use std::io::{self, Cursor};
use std::path::Path;
use std::result;

use curl::http;
use curl::http::handle::Method::{Put, Get, Delete};
use curl::http::handle::{Method, Request};
use rustc_serialize::json;

pub struct Registry {
    host: String,
    token: Option<String>,
    handle: http::Handle,
}

pub type Result<T> = result::Result<T, Error>;

#[derive(PartialEq, Clone, Copy)]
pub enum Auth {
    Authorized,
    Unauthorized
}

pub enum Error {
    Curl(curl::ErrCode),
    NotOkResponse(http::Response),
    NonUtf8Body,
    Api(Vec<String>),
    Unauthorized,
    TokenMissing,
    Io(io::Error),
}

#[derive(RustcDecodable)]
pub struct Crate {
    pub name: String,
    pub description: Option<String>,
    pub max_version: String
}

#[derive(RustcEncodable)]
pub struct NewCrate {
    pub name: String,
    pub vers: String,
    pub deps: Vec<NewCrateDependency>,
    pub features: HashMap<String, Vec<String>>,
    pub authors: Vec<String>,
    pub description: Option<String>,
    pub documentation: Option<String>,
    pub homepage: Option<String>,
    pub readme: Option<String>,
    pub keywords: Vec<String>,
    pub license: Option<String>,
    pub license_file: Option<String>,
    pub repository: Option<String>,
}

#[derive(RustcEncodable)]
pub struct NewCrateDependency {
    pub optional: bool,
    pub default_features: bool,
    pub name: String,
    pub features: Vec<String>,
    pub version_req: String,
    pub target: Option<String>,
    pub kind: String,
}

#[derive(RustcDecodable)]
pub struct User {
    pub id: u32,
    pub login: String,
    pub avatar: Option<String>,
    pub email: Option<String>,
    pub name: Option<String>,
}

#[derive(RustcDecodable)] struct R { ok: bool }
#[derive(RustcDecodable)] struct ApiErrorList { errors: Vec<ApiError> }
#[derive(RustcDecodable)] struct ApiError { detail: String }
#[derive(RustcEncodable)] struct OwnersReq<'a> { users: &'a [&'a str] }
#[derive(RustcDecodable)] struct Users { users: Vec<User> }
#[derive(RustcDecodable)] struct Crates { crates: Vec<Crate> }

impl Registry {
    pub fn new(host: String, token: Option<String>) -> Registry {
        Registry::new_handle(host, token, http::Handle::new())
    }

    pub fn new_handle(host: String, token: Option<String>,
                      handle: http::Handle) -> Registry {
        Registry {
            host: host,
            token: token,
            handle: handle,
        }
    }

    pub fn add_owners(&mut self, krate: &str, owners: &[&str]) -> Result<()> {
        let body = json::encode(&OwnersReq { users: owners }).unwrap();
        let body = try!(self.put(format!("/crates/{}/owners", krate),
                                 body.as_bytes()));
        assert!(json::decode::<R>(&body).unwrap().ok);
        Ok(())
    }

    pub fn remove_owners(&mut self, krate: &str, owners: &[&str]) -> Result<()> {
        let body = json::encode(&OwnersReq { users: owners }).unwrap();
        let body = try!(self.delete(format!("/crates/{}/owners", krate),
                                    Some(body.as_bytes())));
        assert!(json::decode::<R>(&body).unwrap().ok);
        Ok(())
    }

    pub fn list_owners(&mut self, krate: &str) -> Result<Vec<User>> {
        let body = try!(self.get(format!("/crates/{}/owners", krate)));
        Ok(json::decode::<Users>(&body).unwrap().users)
    }

    pub fn publish(&mut self, krate: &NewCrate, tarball: &Path) -> Result<()> {
        let json = json::encode(krate).unwrap();
        // Prepare the body. The format of the upload request is:
        //
        //      <le u32 of json>
        //      <json request> (metadata for the package)
        //      <le u32 of tarball>
        //      <source tarball>
        let stat = try!(fs::metadata(tarball).map_err(Error::Io));
        let header = {
            let mut w = Vec::new();
            w.extend([
                (json.len() >>  0) as u8,
                (json.len() >>  8) as u8,
                (json.len() >> 16) as u8,
                (json.len() >> 24) as u8,
            ].iter().map(|x| *x));
            w.extend(json.as_bytes().iter().map(|x| *x));
            w.extend([
                (stat.len() >>  0) as u8,
                (stat.len() >>  8) as u8,
                (stat.len() >> 16) as u8,
                (stat.len() >> 24) as u8,
            ].iter().map(|x| *x));
            w
        };
        let tarball = try!(File::open(tarball).map_err(Error::Io));
        let size = stat.len() as usize + header.len();
        let mut body = Cursor::new(header).chain(tarball);

        let url = format!("{}/api/v1/crates/new", self.host);

        let token = match self.token.as_ref() {
            Some(s) => s,
            None => return Err(Error::TokenMissing),
        };
        let request = self.handle.put(url, &mut body)
            .content_length(size)
            .header("Accept", "application/json")
            .header("Authorization", &token);
        let response = handle(request.exec());
        let _body = try!(response);
        Ok(())
    }

    pub fn search(&mut self, query: &str) -> Result<Vec<Crate>> {
        let body = try!(self.req(format!("/crates?q={}", query), None, Get,
                                 Auth::Unauthorized));

        Ok(json::decode::<Crates>(&body).unwrap().crates)
    }

    pub fn yank(&mut self, krate: &str, version: &str) -> Result<()> {
        let body = try!(self.delete(format!("/crates/{}/{}/yank", krate, version),
                                    None));
        assert!(json::decode::<R>(&body).unwrap().ok);
        Ok(())
    }

    pub fn unyank(&mut self, krate: &str, version: &str) -> Result<()> {
        let body = try!(self.put(format!("/crates/{}/{}/unyank", krate, version),
                                 &[]));
        assert!(json::decode::<R>(&body).unwrap().ok);
        Ok(())
    }

    fn put(&mut self, path: String, b: &[u8]) -> Result<String> {
        self.req(path, Some(b), Put, Auth::Authorized)
    }

    fn get(&mut self, path: String) -> Result<String> {
        self.req(path, None, Get, Auth::Authorized)
    }

    fn delete(&mut self, path: String, b: Option<&[u8]>) -> Result<String> {
        self.req(path, b, Delete, Auth::Authorized)
    }

    fn req(&mut self, path: String, body: Option<&[u8]>,
           method: Method, authorized: Auth) -> Result<String> {
        let mut req = Request::new(&mut self.handle, method)
                              .uri(format!("{}/api/v1{}", self.host, path))
                              .header("Accept", "application/json")
                              .content_type("application/json");

        if authorized == Auth::Authorized {
            let token = match self.token.as_ref() {
                Some(s) => s,
                None => return Err(Error::TokenMissing),
            };
            req = req.header("Authorization", &token);
        }
        match body {
            Some(b) => req = req.body(b),
            None => {}
        }
        handle(req.exec())
    }
}

fn handle(response: result::Result<http::Response, curl::ErrCode>)
          -> Result<String> {
    let response = try!(response.map_err(Error::Curl));
    match response.get_code() {
        0 => {} // file upload url sometimes
        200 => {}
        403 => return Err(Error::Unauthorized),
        _ => return Err(Error::NotOkResponse(response))
    }

    let body = match String::from_utf8(response.move_body()) {
        Ok(body) => body,
        Err(..) => return Err(Error::NonUtf8Body),
    };
    match json::decode::<ApiErrorList>(&body) {
        Ok(errors) => {
            return Err(Error::Api(errors.errors.into_iter().map(|s| s.detail)
                                        .collect()))
        }
        Err(..) => {}
    }
    Ok(body)
}

impl fmt::Display for Error {
    #[allow(deprecated)] // connect => join in 1.3
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::NonUtf8Body => write!(f, "response body was not utf-8"),
            Error::Curl(ref err) => write!(f, "http error: {}", err),
            Error::NotOkResponse(ref resp) => {
                write!(f, "failed to get a 200 OK response: {}", resp)
            }
            Error::Api(ref errs) => {
                write!(f, "api errors: {}", errs.connect(", "))
            }
            Error::Unauthorized => write!(f, "unauthorized API access"),
            Error::TokenMissing => write!(f, "no upload token found, please run `cargo login`"),
            Error::Io(ref e) => write!(f, "io error: {}", e),
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
mod common;

use common::util::*;

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

#[test]
fn test_single_name_value_pair() {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let out = ucmd.arg("FOO=bar").run().stdout;

    assert!(out.lines().any(|line| line == "FOO=bar"));
}

#[test]
fn test_multiple_name_value_pairs() {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let out = ucmd.arg("FOO=bar")
                  .arg("ABC=xyz")
                  .run()
                  .stdout;

    assert_eq!(out.lines().filter(|&line| line == "FOO=bar" || line == "ABC=xyz").count(),
               2);
}

#[test]
fn test_ignore_environment() {
    let ts = TestSet::new(UTIL_NAME);

    let out = ts.util_cmd()
                .arg("-i")
                .run()
                .stdout;

    assert_eq!(out, "");

    let out = ts.util_cmd()
                .arg("-")
                .run()
                .stdout;

    assert_eq!(out, "");
}

#[test]
fn test_null_delimiter() {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let out = ucmd.arg("-i")
                  .arg("--null")
                  .arg("FOO=bar")
                  .arg("ABC=xyz")
                  .run()
                  .stdout;

    assert_eq!(out, "FOO=bar\0ABC=xyz\0");
}

#[test]
fn test_unset_variable() {
    // This test depends on the HOME variable being pre-defined by the
    // default shell
    let out = TestSet::new(UTIL_NAME)
                  .util_cmd_keepenv()
                  .arg("-u")
                  .arg("HOME")
                  .run()
                  .stdout;

    assert_eq!(out.lines().any(|line| line.starts_with("HOME=")), false);
}
<commit_msg>tests/env: don't assume vars are ordered<commit_after>#[macro_use]
mod common;

use common::util::*;

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

#[test]
fn test_single_name_value_pair() {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let out = ucmd.arg("FOO=bar").run().stdout;

    assert!(out.lines().any(|line| line == "FOO=bar"));
}

#[test]
fn test_multiple_name_value_pairs() {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let out = ucmd.arg("FOO=bar")
                  .arg("ABC=xyz")
                  .run()
                  .stdout;

    assert_eq!(out.lines().filter(|&line| line == "FOO=bar" || line == "ABC=xyz").count(),
               2);
}

#[test]
fn test_ignore_environment() {
    let ts = TestSet::new(UTIL_NAME);

    let out = ts.util_cmd()
                .arg("-i")
                .run()
                .stdout;

    assert_eq!(out, "");

    let out = ts.util_cmd()
                .arg("-")
                .run()
                .stdout;

    assert_eq!(out, "");
}

#[test]
fn test_null_delimiter() {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let out = ucmd.arg("-i")
                  .arg("--null")
                  .arg("FOO=bar")
                  .arg("ABC=xyz")
                  .run()
                  .stdout;

    let mut vars : Vec<_> = out.split('\0').collect();
    assert_eq!(vars.len(), 3);
    vars.sort();
    assert_eq!(vars[0], "");
    assert_eq!(vars[1], "ABC=xyz");
    assert_eq!(vars[2], "FOO=bar");
}

#[test]
fn test_unset_variable() {
    // This test depends on the HOME variable being pre-defined by the
    // default shell
    let out = TestSet::new(UTIL_NAME)
                  .util_cmd_keepenv()
                  .arg("-u")
                  .arg("HOME")
                  .run()
                  .stdout;

    assert_eq!(out.lines().any(|line| line.starts_with("HOME=")), false);
}
<|endoftext|>


<commit_before>#![cfg(feature = "toml")]

extern crate config;
extern crate float_cmp;
extern crate serde;

#[macro_use]
extern crate serde_derive;

use config::*;
use float_cmp::ApproxEqUlps;
use std::collections::{HashMap, HashSet};

#[derive(Debug, Deserialize)]
struct Place {
    name: String,
    longitude: f64,
    latitude: f64,
    favorite: bool,
    telephone: Option<String>,
    reviews: u64,
    rating: Option<f32>,
}

#[derive(Debug, Deserialize)]
struct Settings {
    debug: f64,
    production: Option<String>,
    place: Place,
}

fn make() -> Config {
    let mut c = Config::default();
    c.merge(File::new("tests/Settings", FileFormat::Toml))
        .unwrap();

    c
}

#[test]
fn test_not_found() {
    let c = make();
    let res = c.get::<bool>("not_found");

    assert!(res.is_err());
    assert_eq!(
        res.unwrap_err().to_string(),
        "configuration property \"not_found\" not found".to_string()
    );
}

#[test]
fn test_scalar() {
    let c = make();

    assert_eq!(c.get("debug").ok(), Some(true));
    assert_eq!(c.get("production").ok(), Some(false));
}

#[test]
fn test_scalar_type_loose() {
    let c = make();

    assert_eq!(c.get("debug").ok(), Some(true));
    assert_eq!(c.get("debug").ok(), Some("true".to_string()));
    assert_eq!(c.get("debug").ok(), Some(1));
    assert_eq!(c.get("debug").ok(), Some(1.0));

    assert_eq!(c.get("debug_s").ok(), Some(true));
    assert_eq!(c.get("debug_s").ok(), Some("true".to_string()));
    assert_eq!(c.get("debug_s").ok(), Some(1));
    assert_eq!(c.get("debug_s").ok(), Some(1.0));

    assert_eq!(c.get("production").ok(), Some(false));
    assert_eq!(c.get("production").ok(), Some("false".to_string()));
    assert_eq!(c.get("production").ok(), Some(0));
    assert_eq!(c.get("production").ok(), Some(0.0));

    assert_eq!(c.get("production_s").ok(), Some(false));
    assert_eq!(c.get("production_s").ok(), Some("false".to_string()));
    assert_eq!(c.get("production_s").ok(), Some(0));
    assert_eq!(c.get("production_s").ok(), Some(0.0));
}

#[test]
fn test_get_scalar_path() {
    let c = make();

    assert_eq!(c.get("place.favorite").ok(), Some(false));
    assert_eq!(
        c.get("place.creator.name").ok(),
        Some("John Smith".to_string())
    );
}

#[test]
fn test_get_scalar_path_subscript() {
    let c = make();

    assert_eq!(c.get("arr[2]").ok(), Some(3));
    assert_eq!(c.get("items[0].name").ok(), Some("1".to_string()));
    assert_eq!(c.get("items[1].name").ok(), Some("2".to_string()));
    assert_eq!(c.get("items[-1].name").ok(), Some("2".to_string()));
    assert_eq!(c.get("items[-2].name").ok(), Some("1".to_string()));
}

#[test]
fn test_map() {
    let c = make();
    let m: HashMap<String, Value> = c.get("place").unwrap();

    assert_eq!(m.len(), 8);
    assert_eq!(
        m["name"].clone().into_str().unwrap(),
        "Torre di Pisa".to_string()
    );
    assert_eq!(m["reviews"].clone().into_int().unwrap(), 3866);
}

#[test]
fn test_map_str() {
    let c = make();
    let m: HashMap<String, String> = c.get("place.creator").unwrap();

    assert_eq!(m.len(), 1);
    assert_eq!(m["name"], "John Smith".to_string());
}

#[test]
fn test_map_struct() {
    #[derive(Debug, Deserialize)]
    struct Settings {
        place: HashMap<String, Value>,
    }

    let c = make();
    let s: Settings = c.try_into().unwrap();

    assert_eq!(s.place.len(), 8);
    assert_eq!(
        s.place["name"].clone().into_str().unwrap(),
        "Torre di Pisa".to_string()
    );
    assert_eq!(s.place["reviews"].clone().into_int().unwrap(), 3866);
}

#[test]
fn test_file_struct() {
    let c = make();

    // Deserialize the entire file as single struct
    let s: Settings = c.try_into().unwrap();

    assert!(s.debug.approx_eq_ulps(&1.0, 2));
    assert_eq!(s.production, Some("false".to_string()));
    assert_eq!(s.place.name, "Torre di Pisa");
    assert!(s.place.longitude.approx_eq_ulps(&43.7224985, 2));
    assert!(s.place.latitude.approx_eq_ulps(&10.3970522, 2));
    assert_eq!(s.place.favorite, false);
    assert_eq!(s.place.reviews, 3866);
    assert_eq!(s.place.rating, Some(4.5));
    assert_eq!(s.place.telephone, None);
}

#[test]
fn test_scalar_struct() {
    let c = make();

    // Deserialize a scalar struct that has lots of different
    // data types
    let p: Place = c.get("place").unwrap();

    assert_eq!(p.name, "Torre di Pisa");
    assert!(p.longitude.approx_eq_ulps(&43.7224985, 2));
    assert!(p.latitude.approx_eq_ulps(&10.3970522, 2));
    assert_eq!(p.favorite, false);
    assert_eq!(p.reviews, 3866);
    assert_eq!(p.rating, Some(4.5));
    assert_eq!(p.telephone, None);
}

#[test]
fn test_array_scalar() {
    let c = make();
    let arr: Vec<i64> = c.get("arr").unwrap();

    assert_eq!(arr.len(), 10);
    assert_eq!(arr[3], 4);
}

#[test]
fn test_struct_array() {
    #[derive(Debug, Deserialize)]
    struct Settings {
        #[serde(rename = "arr")]
        elements: Vec<String>,
    }

    let c = make();
    let s: Settings = c.try_into().unwrap();

    assert_eq!(s.elements.len(), 10);
    assert_eq!(s.elements[3], "4".to_string());
}

#[test]
fn test_enum() {
    #[derive(Debug, Deserialize, PartialEq)]
    #[serde(rename_all = "lowercase")]
    enum Diode {
        Off,
        Brightness(i32),
        Blinking(i32, i32),
        Pattern { name: String, inifinite: bool },
    }
    #[derive(Debug, Deserialize)]
    struct Settings {
        diodes: HashMap<String, Diode>,
    }

    let c = make();
    let s: Settings = c.try_into().unwrap();

    assert_eq!(s.diodes["green"], Diode::Off);
    assert_eq!(s.diodes["red"], Diode::Brightness(100));
    assert_eq!(s.diodes["blue"], Diode::Blinking(300, 700));
    assert_eq!(s.diodes["white"], Diode::Pattern{name: "christmas".into(), inifinite: true,});
}

#[test]
fn test_enum_key() {
    #[derive(Debug, Deserialize, PartialEq, Eq, Hash)]
    enum Quark {
        Up,
        Down,
        Strange,
        Charm,
        Bottom,
        Top,
    }

    #[derive(Debug, Deserialize)]
    struct Settings {
        proton: HashMap<Quark, usize>,
        // Just to make sure that set keys work too.
        quarks: HashSet<Quark>,
    }

    let c = make();
    let s: Settings = c.try_into().unwrap();

    assert_eq!(s.proton[&Quark::Up], 2);
    assert_eq!(s.quarks.len(), 6);
}

#[test]
fn test_int_key() {
    #[derive(Debug, Deserialize, PartialEq)]
    struct Settings {
        divisors: HashMap<u32, u32>,
    }

    let c = make();
    let s: Settings = c.try_into().unwrap();
    assert_eq!(s.divisors[&4], 3);
    assert_eq!(s.divisors.len(), 4);
}
<commit_msg>Fix test for enum keys as auto lowercase was disabled<commit_after>#![cfg(feature = "toml")]

extern crate config;
extern crate float_cmp;
extern crate serde;

#[macro_use]
extern crate serde_derive;

use config::*;
use float_cmp::ApproxEqUlps;
use std::collections::{HashMap, HashSet};

#[derive(Debug, Deserialize)]
struct Place {
    name: String,
    longitude: f64,
    latitude: f64,
    favorite: bool,
    telephone: Option<String>,
    reviews: u64,
    rating: Option<f32>,
}

#[derive(Debug, Deserialize)]
struct Settings {
    debug: f64,
    production: Option<String>,
    place: Place,
}

fn make() -> Config {
    let mut c = Config::default();
    c.merge(File::new("tests/Settings", FileFormat::Toml))
        .unwrap();

    c
}

#[test]
fn test_not_found() {
    let c = make();
    let res = c.get::<bool>("not_found");

    assert!(res.is_err());
    assert_eq!(
        res.unwrap_err().to_string(),
        "configuration property \"not_found\" not found".to_string()
    );
}

#[test]
fn test_scalar() {
    let c = make();

    assert_eq!(c.get("debug").ok(), Some(true));
    assert_eq!(c.get("production").ok(), Some(false));
}

#[test]
fn test_scalar_type_loose() {
    let c = make();

    assert_eq!(c.get("debug").ok(), Some(true));
    assert_eq!(c.get("debug").ok(), Some("true".to_string()));
    assert_eq!(c.get("debug").ok(), Some(1));
    assert_eq!(c.get("debug").ok(), Some(1.0));

    assert_eq!(c.get("debug_s").ok(), Some(true));
    assert_eq!(c.get("debug_s").ok(), Some("true".to_string()));
    assert_eq!(c.get("debug_s").ok(), Some(1));
    assert_eq!(c.get("debug_s").ok(), Some(1.0));

    assert_eq!(c.get("production").ok(), Some(false));
    assert_eq!(c.get("production").ok(), Some("false".to_string()));
    assert_eq!(c.get("production").ok(), Some(0));
    assert_eq!(c.get("production").ok(), Some(0.0));

    assert_eq!(c.get("production_s").ok(), Some(false));
    assert_eq!(c.get("production_s").ok(), Some("false".to_string()));
    assert_eq!(c.get("production_s").ok(), Some(0));
    assert_eq!(c.get("production_s").ok(), Some(0.0));
}

#[test]
fn test_get_scalar_path() {
    let c = make();

    assert_eq!(c.get("place.favorite").ok(), Some(false));
    assert_eq!(
        c.get("place.creator.name").ok(),
        Some("John Smith".to_string())
    );
}

#[test]
fn test_get_scalar_path_subscript() {
    let c = make();

    assert_eq!(c.get("arr[2]").ok(), Some(3));
    assert_eq!(c.get("items[0].name").ok(), Some("1".to_string()));
    assert_eq!(c.get("items[1].name").ok(), Some("2".to_string()));
    assert_eq!(c.get("items[-1].name").ok(), Some("2".to_string()));
    assert_eq!(c.get("items[-2].name").ok(), Some("1".to_string()));
}

#[test]
fn test_map() {
    let c = make();
    let m: HashMap<String, Value> = c.get("place").unwrap();

    assert_eq!(m.len(), 8);
    assert_eq!(
        m["name"].clone().into_str().unwrap(),
        "Torre di Pisa".to_string()
    );
    assert_eq!(m["reviews"].clone().into_int().unwrap(), 3866);
}

#[test]
fn test_map_str() {
    let c = make();
    let m: HashMap<String, String> = c.get("place.creator").unwrap();

    assert_eq!(m.len(), 1);
    assert_eq!(m["name"], "John Smith".to_string());
}

#[test]
fn test_map_struct() {
    #[derive(Debug, Deserialize)]
    struct Settings {
        place: HashMap<String, Value>,
    }

    let c = make();
    let s: Settings = c.try_into().unwrap();

    assert_eq!(s.place.len(), 8);
    assert_eq!(
        s.place["name"].clone().into_str().unwrap(),
        "Torre di Pisa".to_string()
    );
    assert_eq!(s.place["reviews"].clone().into_int().unwrap(), 3866);
}

#[test]
fn test_file_struct() {
    let c = make();

    // Deserialize the entire file as single struct
    let s: Settings = c.try_into().unwrap();

    assert!(s.debug.approx_eq_ulps(&1.0, 2));
    assert_eq!(s.production, Some("false".to_string()));
    assert_eq!(s.place.name, "Torre di Pisa");
    assert!(s.place.longitude.approx_eq_ulps(&43.7224985, 2));
    assert!(s.place.latitude.approx_eq_ulps(&10.3970522, 2));
    assert_eq!(s.place.favorite, false);
    assert_eq!(s.place.reviews, 3866);
    assert_eq!(s.place.rating, Some(4.5));
    assert_eq!(s.place.telephone, None);
}

#[test]
fn test_scalar_struct() {
    let c = make();

    // Deserialize a scalar struct that has lots of different
    // data types
    let p: Place = c.get("place").unwrap();

    assert_eq!(p.name, "Torre di Pisa");
    assert!(p.longitude.approx_eq_ulps(&43.7224985, 2));
    assert!(p.latitude.approx_eq_ulps(&10.3970522, 2));
    assert_eq!(p.favorite, false);
    assert_eq!(p.reviews, 3866);
    assert_eq!(p.rating, Some(4.5));
    assert_eq!(p.telephone, None);
}

#[test]
fn test_array_scalar() {
    let c = make();
    let arr: Vec<i64> = c.get("arr").unwrap();

    assert_eq!(arr.len(), 10);
    assert_eq!(arr[3], 4);
}

#[test]
fn test_struct_array() {
    #[derive(Debug, Deserialize)]
    struct Settings {
        #[serde(rename = "arr")]
        elements: Vec<String>,
    }

    let c = make();
    let s: Settings = c.try_into().unwrap();

    assert_eq!(s.elements.len(), 10);
    assert_eq!(s.elements[3], "4".to_string());
}

#[test]
fn test_enum() {
    #[derive(Debug, Deserialize, PartialEq)]
    #[serde(rename_all = "lowercase")]
    enum Diode {
        Off,
        Brightness(i32),
        Blinking(i32, i32),
        Pattern { name: String, inifinite: bool },
    }
    #[derive(Debug, Deserialize)]
    struct Settings {
        diodes: HashMap<String, Diode>,
    }

    let c = make();
    let s: Settings = c.try_into().unwrap();

    assert_eq!(s.diodes["green"], Diode::Off);
    assert_eq!(s.diodes["red"], Diode::Brightness(100));
    assert_eq!(s.diodes["blue"], Diode::Blinking(300, 700));
    assert_eq!(s.diodes["white"], Diode::Pattern{name: "christmas".into(), inifinite: true,});
}

#[test]
fn test_enum_key() {
    #[derive(Debug, Deserialize, PartialEq, Eq, Hash)]
    #[serde(rename_all = "lowercase")]
    enum Quark {
        Up,
        Down,
        Strange,
        Charm,
        Bottom,
        Top,
    }

    #[derive(Debug, Deserialize)]
    struct Settings {
        proton: HashMap<Quark, usize>,
        // Just to make sure that set keys work too.
        quarks: HashSet<Quark>,
    }

    let c = make();
    let s: Settings = c.try_into().unwrap();

    assert_eq!(s.proton[&Quark::Up], 2);
    assert_eq!(s.quarks.len(), 6);
}

#[test]
fn test_int_key() {
    #[derive(Debug, Deserialize, PartialEq)]
    struct Settings {
        divisors: HashMap<u32, u32>,
    }

    let c = make();
    let s: Settings = c.try_into().unwrap();
    assert_eq!(s.divisors[&4], 3);
    assert_eq!(s.divisors.len(), 4);
}
<|endoftext|>


<commit_before>extern crate gradr_backend;
extern crate hyper;
extern crate github;
extern crate url;

use std::comm::sync_channel;
use std::io::timer;
use std::sync::{Arc, RWLock};
use std::time::Duration;

use gradr_backend::builder::{WholeBuildable, ToWholeBuildable};
use gradr_backend::database::Database;
use gradr_backend::database::sqlite::SqliteDatabase;
use gradr_backend::database::testing::TestDatabase;
use gradr_backend::notification_listener::{NotificationSource, GitHubServer};
use gradr_backend::notification_listener::testing::TestNotificationSource;
use gradr_backend::worker::worker_loop_step;

use self::github::server::testing::{send_to_server, SendPush};
use self::github::notification::PushNotification;

use self::url::Url;
use self::hyper::{IpAddr, Ipv4Addr, Port};

static ADDR: IpAddr = Ipv4Addr(127, 0, 0, 1);

fn end_to_end<B : WholeBuildable, E : ToWholeBuildable<B>, D : Database<E>, N : NotificationSource<E>>(
    db: D,
    not_src: N,
    to_send: Vec<E>,
    sender: |E| -> (),
    stop_all: || -> (),
    checker: |&D| -> bool) { // returns true if it expects more results

    let done1 = Arc::new(RWLock::new(false));
    let done2 = done1.clone();

    let db1 = Arc::new(db);
    let db2 = db1.clone();
    let db3 = db1.clone();

    spawn(proc() {
        while not_src.notification_event_loop_step(&*db1) {}
    });

    spawn(proc() {
        while !*done1.read() {
            worker_loop_step(&*db2);
        }
    });

    for e in to_send.into_iter() {
        sender(e);
    }

    stop_all();

    let mut success = false;

    for _ in range(0, 300u) {
        timer::sleep(Duration::milliseconds(10));
        if !checker(&*db3) {
            success = true;
            break;
        }
    }

    let mut val = done2.write();
    *val = true;
    val.downgrade();

    assert!(success);
}

fn end_to_end_test_not_source<A : Database<Path>>(db: A) {
    let (notification_sender, notification_recv) = sync_channel(10);
    let not_src = TestNotificationSource::new(notification_recv);
    let to_send = vec!(Path::new("test/end_to_end"));
    let sender = |path: Path| {
        notification_sender.send(Some(path));
    };
    let stop_all = || {
        notification_sender.send(None);
    };
    let checker = |db: &A| {
        match db.results_for_entry(Path::new("test/end_to_end")) {
            Some(ref s) => {
                assert!(s.contains("test1: Pass"));
                assert!(s.contains("test2: Fail"));
                false
            },
            None => true
        }
    };

    end_to_end(db, not_src, to_send, sender, stop_all, checker);
}

fn end_to_end_test_github_source<A : Database<PushNotification>>(db: A, port: Port) {
    let server = GitHubServer::new(ADDR, port);
    let not_src = server.event_loop().unwrap();
    let not1 =
        PushNotification {
            clone_url: Url::parse("https://github.com/scalableinternetservices/GradrBackend.git").unwrap(),
            branch: "master".to_string()
        };

    let to_send = vec!(not1);
    let sender = |not: PushNotification| {
        send_to_server(SendPush(not).to_string().as_slice(), ADDR, port)
    };
    let stop_all = || {
        //not_src1.wrapped.send_finish()
    };
    let checker = |db: &A| {
        let not2 =
            PushNotification {
                clone_url: Url::parse("https://github.com/scalableinternetservices/GradrBackend.git").unwrap(),
                branch: "master".to_string()
            };

        match db.results_for_entry(not2) {
            Some(ref s) => {
                assert!(s.contains("test1: Pass"));
                assert!(s.contains("test2: Fail"));
                false
            },
            None => true
        }
    };

    end_to_end(db, not_src, to_send, sender, stop_all, checker);
}

#[test]
fn end_to_end_test_not_source_in_memory() {
    end_to_end_test_not_source(TestDatabase::new());
}

#[test]
fn end_to_end_sqlite() {
    end_to_end_test_not_source(SqliteDatabase::new().unwrap());
}
<commit_msg>Added tests.  Can't actually run them because THIS LANGUAGE CHANGES EVERY 30 HOURS.<commit_after>extern crate gradr_backend;
extern crate hyper;
extern crate github;
extern crate url;

use std::comm::sync_channel;
use std::io::timer;
use std::sync::{Arc, RWLock};
use std::time::Duration;

use gradr_backend::builder::{WholeBuildable, ToWholeBuildable};
use gradr_backend::database::Database;
use gradr_backend::database::sqlite::SqliteDatabase;
use gradr_backend::database::testing::TestDatabase;
use gradr_backend::notification_listener::{NotificationSource, GitHubServer};
use gradr_backend::notification_listener::testing::TestNotificationSource;
use gradr_backend::worker::worker_loop_step;

use self::github::server::testing::{send_to_server, SendPush};
use self::github::notification::PushNotification;

use self::url::Url;
use self::hyper::{IpAddr, Ipv4Addr, Port};

static ADDR: IpAddr = Ipv4Addr(127, 0, 0, 1);

fn end_to_end<B : WholeBuildable, E : ToWholeBuildable<B>, D : Database<E>, N : NotificationSource<E>>(
    db: D,
    not_src: N,
    to_send: Vec<E>,
    sender: |E| -> (),
    stop_all: || -> (),
    checker: |&D| -> bool) { // returns true if it expects more results

    let done1 = Arc::new(RWLock::new(false));
    let done2 = done1.clone();

    let db1 = Arc::new(db);
    let db2 = db1.clone();
    let db3 = db1.clone();

    spawn(proc() {
        while not_src.notification_event_loop_step(&*db1) {}
    });

    spawn(proc() {
        while !*done1.read() {
            worker_loop_step(&*db2);
        }
    });

    for e in to_send.into_iter() {
        sender(e);
    }

    stop_all();

    let mut success = false;

    for _ in range(0, 300u) {
        timer::sleep(Duration::milliseconds(10));
        if !checker(&*db3) {
            success = true;
            break;
        }
    }

    let mut val = done2.write();
    *val = true;
    val.downgrade();

    assert!(success);
}

fn end_to_end_test_not_source<A : Database<Path>>(db: A) {
    let (notification_sender, notification_recv) = sync_channel(10);
    let not_src = TestNotificationSource::new(notification_recv);
    let to_send = vec!(Path::new("test/end_to_end"));
    let sender = |path: Path| {
        notification_sender.send(Some(path));
    };
    let stop_all = || {
        notification_sender.send(None);
    };
    let checker = |db: &A| {
        match db.results_for_entry(Path::new("test/end_to_end")) {
            Some(ref s) => {
                assert!(s.contains("test1: Pass"));
                assert!(s.contains("test2: Fail"));
                false
            },
            None => true
        }
    };

    end_to_end(db, not_src, to_send, sender, stop_all, checker);
}

fn end_to_end_github_not_source<A : Database<PushNotification>>(db: A, port: Port) {
    let server = GitHubServer::new(ADDR, port);
    let not_src = server.event_loop().unwrap();
    let not1 =
        PushNotification {
            clone_url: Url::parse("https://github.com/scalableinternetservices/GradrBackend.git").unwrap(),
            branch: "testing".to_string()
        };

    let to_send = vec!(not1);
    let sender = |not: PushNotification| {
        send_to_server(SendPush(not).to_string().as_slice(), ADDR, port)
    };
    let stop_all = || {
        //not_src1.wrapped.send_finish()
    };
    let checker = |db: &A| {
        let not2 =
            PushNotification {
                clone_url: Url::parse("https://github.com/scalableinternetservices/GradrBackend.git").unwrap(),
                branch: "master".to_string()
            };

        match db.results_for_entry(not2) {
            Some(ref s) => {
                assert!(s.contains("test1: Pass"));
                assert!(s.contains("test2: Fail"));
                false
            },
            None => true
        }
    };

    end_to_end(db, not_src, to_send, sender, stop_all, checker);
}

#[test]
fn end_to_end_test_not_source_in_memory() {
    end_to_end_test_not_source(TestDatabase::new());
}

#[test]
fn end_to_end_test_not_source_sqlite() {
    end_to_end_test_not_source(SqliteDatabase::new().unwrap());
}

#[test]
fn end_to_end_github_not_source_in_memory() {
    end_to_end_github_not_source(TestDatabase::new());
}

#[test]
fn end_to_end_github_not_source_sqlite() {
    end_to_end_github_not_source(SqliteDatabase::new().unwrap());
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate fsm;

use fsm::{ThreadedFsm, LocalFsm, Fsm, FsmContext, StateFn, FsmHandler};

#[derive(Debug, Clone)]
pub struct Context {
    pub view_number: u64,
    pub op_number: u64
}

impl FsmContext for Context {
    fn new() -> Context {
        Context {
            view_number: 0,
            op_number: 0
        }
    }
}

#[derive(Debug)]
pub enum Msg {
    Prepare,
    PrepareOk
}

#[derive(Debug)]
pub struct VrHandler;

impl FsmHandler for VrHandler {
    type Context = Context;
    type Msg = Msg;

    fn initial_state() -> StateFn<VrHandler> {
        next!(normal)
    }
}

pub fn normal(ctx: &mut Context, _msg: Msg) -> StateFn<VrHandler> {
    // Mutate ctx as needed
    ctx.view_number += 1;
    // Transition to recovering state
    next!(recovering)
}

pub fn recovering(ctx: &mut Context, _msg: Msg) -> StateFn<VrHandler> {
    // Mutate ctx as needed
    ctx.op_number += 1;
    // Transition to normal state
    next!(normal)
}

fn assert_state_transitions<T: Fsm<VrHandler>>(mut fsm: T) {
    fsm.trace_on("/tmp/fsm_trace.txt");
    let (name, ctx) = fsm.get_state();
    assert_eq!(name, "normal");
    assert_eq!(ctx.view_number, 0);
    fsm.send_msg(Msg::Prepare);
    let (name, ctx) = fsm.get_state();
    assert_eq!(name, "recovering");
    assert_eq!(ctx.view_number, 1);
}

#[test]
fn test_threaded() {
    let fsm = ThreadedFsm::new();
    assert_state_transitions(fsm);
}

#[test]
fn test_local() {
    let fsm = LocalFsm::new();
    assert_state_transitions(fsm);
}
<commit_msg>Add a full example to tests/lib.rs<commit_after>//! This is a simple example of a fsm for feeding a cat. The states of the fsm are the states of
//! the cat food bowl. Our cat is very whiny and will always be fed when her bowl is empty and she
//! meows. If there is already food in the bowl, she will have to eat it before we give her more.

#[macro_use]
extern crate fsm;

use fsm::{ThreadedFsm, LocalFsm, Fsm, FsmContext, StateFn, FsmHandler};

#[derive(Debug, Clone)]
pub struct Context {
    pub contents: u8
}

impl FsmContext for Context {
    fn new() -> Context {
        Context {
            contents: 0 // The bowl starts off empty
        }
    }
}

#[derive(Debug)]
pub enum Msg {
    Meow,
    Eat(u8) // % of food to eat
}

#[derive(Debug)]
pub struct BowlHandler;

impl FsmHandler for BowlHandler {
    type Context = Context;
    type Msg = Msg;

    fn initial_state() -> StateFn<BowlHandler> {
        next!(empty)
    }
}

pub fn empty(ctx: &mut Context, msg: Msg) -> StateFn<BowlHandler> {
    if let Msg::Meow = msg {
        // Fill the bowl
        ctx.contents = 100;
        next!(full)
    } else {
        // Can't eat out of an empty bowl
        next!(empty)
    }
}

pub fn full(ctx: &mut Context, msg: Msg) -> StateFn<BowlHandler> {
    if let Msg::Eat(pct) = msg {
        if pct >= ctx.contents {
            ctx.contents = 0;
            next!(empty)
        } else {
            ctx.contents -= pct;
            next!(full)
        }
    } else {
        next!(full)
    }
}

fn assert_state_transitions<T: Fsm<BowlHandler>>(mut fsm: T) {
    fsm.trace_on("/tmp/fsm_trace.txt");
    let (name, ctx) = fsm.get_state();
    assert_eq!(name, "empty");
    assert_eq!(ctx.contents, 0);
    fsm.send_msg(Msg::Meow);
    let (name, ctx) = fsm.get_state();
    assert_eq!(name, "full");
    assert_eq!(ctx.contents, 100);
    fsm.send_msg(Msg::Eat(30));
    let (name, ctx) = fsm.get_state();
    assert_eq!(name, "full");
    assert_eq!(ctx.contents, 70);
    fsm.send_msg(Msg::Meow);
    let (name, ctx) = fsm.get_state();
    assert_eq!(name, "full");
    assert_eq!(ctx.contents, 70);
    fsm.send_msg(Msg::Eat(75));
    let (name, ctx) = fsm.get_state();
    assert_eq!(name, "empty");
    assert_eq!(ctx.contents, 0);
}

#[test]
fn test_threaded() {
    let fsm = ThreadedFsm::new();
    assert_state_transitions(fsm);
}

#[test]
fn test_local() {
    let fsm = LocalFsm::new();
    assert_state_transitions(fsm);
}
<|endoftext|>


<commit_before>extern crate rstate;
use std::time::Duration;
use std::thread;
use rstate::State;
use rstate::Store;
use rstate::Middleware;

enum TestAction {
    Increment,
    Decrement,
    Add(i32),
}

struct TestState {
    pub number: i32,
}

impl State for TestState {
    type Action = TestAction;

    fn reduce(&mut self, action: TestAction) {
        match action {
            TestAction::Add(x) => self.number += x,
            TestAction::Increment => self.number += 1,
            TestAction::Decrement => self.number -= 1,
        }
    }
}

struct TestMiddleware {
    pub counter: i32,
}

impl Middleware<TestState> for TestMiddleware {
    fn dispatch(&mut self, store: Store<TestState, Self>, next: &Fn(TestAction), action: TestAction) {
        let mut store_mut = store.clone();
        let counter = self.counter;
        match action {
            TestAction::Add(_) => (),
            _ => {
                thread::spawn(move || {
                    thread::sleep(Duration::from_millis(5));
                    let number = store_mut.state().number;
                    thread::sleep(Duration::from_millis(15));
                    let next_number = store_mut.state().number;
                    store_mut.dispatch(TestAction::Add(next_number - number + counter));
                });
            }
        }
        self.counter += 1;
        next(action);
    }
}

#[test]
fn store() {
    let state = TestState {
        number: 0,
    };
    let middleware = TestMiddleware {
        counter: 0,
    };
    let mut store = Store::new(state, middleware);

    {
        let current_state = store.state();
        assert_eq!(current_state.number, 0);
    }

    store.dispatch(TestAction::Increment);
    // counter = 0
    assert_eq!(store.state().number, 1);

    thread::sleep(Duration::from_millis(10));

    store.dispatch(TestAction::Add(2));
    // counter = 1
    assert_eq!(store.state().number, 3);

    thread::sleep(Duration::from_millis(15));
    // counter = 2
    assert_eq!(store.state().number, 3 + (3 - 1) + 0); // 5
    // counter = 3
    thread::sleep(Duration::from_millis(15));
    // counter = 4
    assert_eq!(store.state().number, 5);

    store.dispatch(TestAction::Decrement);
    // counter = 5
    assert_eq!(store.state().number, 4);
    store.dispatch(TestAction::Add(-2));
    // counter = 6
    assert_eq!(store.state().number, 2);

    thread::sleep(Duration::from_millis(25));
    assert_eq!(store.state().number, 2 + (2 - 4) + 5);
}
<commit_msg>Modify the test<commit_after>extern crate rstate;
use std::time::Duration;
use std::thread;
use rstate::State;
use rstate::Store;
use rstate::Middleware;

enum TestAction {
    Add(i32),
    Increment,
    Decrement,
    BonusTime, // 20ms Bonus Time
}

struct TestState {
    pub number: i32,
}

impl State for TestState {
    type Action = TestAction;

    fn reduce(&mut self, action: TestAction) {
        match action {
            TestAction::Add(x) => self.number += x,
            TestAction::Increment => self.number += 1,
            TestAction::Decrement => self.number -= 1,
            _ => {},
        }
    }
}

struct TestMiddleware {
    pub counter: i32,
}

impl Middleware<TestState> for TestMiddleware {
    fn dispatch(&mut self, store: Store<TestState, Self>, next: &Fn(TestAction), action: TestAction) {
        match action {
            TestAction::BonusTime => {
                self.counter += 1;

                let mut store_mut = store.clone();
                let counter = self.counter;

                thread::spawn(move || {
                    let number = store_mut.state().number;
                    thread::sleep(Duration::from_millis(20));
                    let next_number = store_mut.state().number;
                    let bonus = (next_number - number) * counter;
                    store_mut.dispatch(TestAction::Add(bonus));
                });
                thread::sleep(Duration::from_millis(1));
            },
            _ => {
                next(action);
            },
        }
    }
}

#[test]
fn store() {
    let state = TestState {
        number: 0,
    };
    let middleware = TestMiddleware {
        counter: 0,
    };
    let mut store = Store::new(state, middleware);

    assert_eq!(store.state().number, 0);

    store.dispatch(TestAction::Increment);
    assert_eq!(store.state().number, 1);

    store.dispatch(TestAction::Add(2));
    assert_eq!(store.state().number, 3);

    // start BonusTime
    store.dispatch(TestAction::BonusTime);

    store.dispatch(TestAction::Add(3));
    assert_eq!(store.state().number, 6);

    store.dispatch(TestAction::Decrement);
    assert_eq!(store.state().number, 5);

    // finish BonusTime
    thread::sleep(Duration::from_millis(25));
    assert_eq!(store.state().number, 5 + (5 - 3) * 1); // 7

    // start BonusTime
    store.dispatch(TestAction::BonusTime);

    store.dispatch(TestAction::Add(-4));
    assert_eq!(store.state().number, 3);

    store.dispatch(TestAction::Increment);
    assert_eq!(store.state().number, 4);

    // finish BonusTime
    thread::sleep(Duration::from_millis(25));
    assert_eq!(store.state().number, 4 + (4 - 7) * 2); // -1
}
<|endoftext|>


<commit_before>//! This handles the XWayland server and any XWayland clients that connect to
//! Way Cooler.

use wlroots::{Compositor, XWaylandManagerHandler};
pub struct XWaylandManager;

impl XWaylandManager {
    pub fn new() -> Self {
        XWaylandManager
    }
}

impl XWaylandManagerHandler for XWaylandManager {
    fn on_ready(&mut self, _: &mut Compositor) {
        ::awesome::lua::setup_lua();
    }
}
<commit_msg>Added bad error handling for awesome set up failure<commit_after>//! This handles the XWayland server and any XWayland clients that connect to
//! Way Cooler.

use awesome;
use std::panic;
use wlroots::{Compositor, XWaylandManagerHandler};

pub struct XWaylandManager;

impl XWaylandManager {
    pub fn new() -> Self {
        XWaylandManager
    }
}

impl XWaylandManagerHandler for XWaylandManager {
    fn on_ready(&mut self, _: &mut Compositor) {
        // TODO Do this properly with Results!
        match panic::catch_unwind(|| ::awesome::lua::setup_lua()) {
            Ok(_) => {},
            Err(err) => {
                awesome::lua::terminate();
                panic::resume_unwind(err)
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate ktensor as k;
use std::sync::{Arc};

#[test]
fn xor() {
    // Variables
    let input_x = Arc::new(k::Variable::new("input_x".to_string(), k::Vec2(0, 2)));
    let target_y = Arc::new(k::Variable::new("target_y".to_string(), k::Vec2(0, 2)));

    // Initialize
    let mut variable_context = k::Context::<f64>::with_capacity(2);
    k::variable::init_f64(vec![input_x.clone(), target_y.clone()], &mut variable_context);

    // Graph
    let layers: usize = 2;
    let mut states = Vec::<Arc<k::State>>::with_capacity(2 * layers);
    let mut graph_head: Arc<k::Graph<f64>> = input_x.clone();

    let w = Arc::new(k::State::new(format!("weight_w_{}", 1), k::Vec2(2, 4)));
    let b = Arc::new(k::State::new(format!("weight_b_{}", 1), k::Vec2(1, 4)));

    let dot = Arc::new(k::op::dot::<f64>(format!("layer_{}_dot", 1), graph_head.clone(), w.clone()));
    let add = Arc::new(k::op::add_f64(format!("layer_{}_add", 1), dot.clone(), b.clone()));

    let relu = Arc::new(k::op::relu_f64(format!("layer_{}_relu", 1), add.clone()));

    graph_head = relu.clone();

    states.push(w.clone());
    states.push(b.clone());

    let w2 = Arc::new(k::State::new(format!("weight_w_{}", 2), k::Vec2(4, 2)));
    let b2 = Arc::new(k::State::new(format!("weight_b_{}", 2), k::Vec2(1, 2)));

    let dot2 = Arc::new(k::op::dot::<f64>(format!("layer_{}_dot", 2), graph_head.clone(), w2.clone()));
    let add2 = Arc::new(k::op::add_f64(format!("layer_{}_add", 2), dot2.clone(), b2.clone()));

    let relu2 = Arc::new(k::op::relu_f64(format!("layer_{}_relu", 2), add2.clone()));

    graph_head = relu2.clone();

    states.push(w2.clone());
    states.push(b2.clone());

    let softmax2 = Arc::new(k::op::softmax_f64(format!("layer_{}_softmax", 2), graph_head.clone()));
    let xentropy2 = Arc::new(k::cost::softmax_cross_entropy_f64(format!("layer_{}_xentropy", 2), softmax2.clone(), target_y.clone()));

    // initialize states
    let mut state_context = k::Context::<f64>::with_capacity(2 * layers);
    k::state::init_f64(states, &mut state_context);

    let training_set = (
        k::Tensor::from_vec(k::Vec2(4, 2), vec![
        0.0, 0.0,
        0.0, 1.0,
        1.0, 0.0,
        1.0, 1.0,
        ]),
        k::Tensor::from_vec(k::Vec2(4, 2), vec![
        0.0, 1.0,
        1.0, 0.0,
        1.0, 0.0,
        0.0, 1.0,
        ]),
    );

    let training_vec = vec![
        (k::Tensor::from_vec(k::Vec2(1, 2), vec![0.0, 0.0,]), k::Tensor::from_vec(k::Vec2(1, 2), vec![0.0, 1.0,])),
        (k::Tensor::from_vec(k::Vec2(1, 2), vec![0.0, 1.0,]), k::Tensor::from_vec(k::Vec2(1, 2), vec![1.0, 0.0,])),
        (k::Tensor::from_vec(k::Vec2(1, 2), vec![1.0, 0.0,]), k::Tensor::from_vec(k::Vec2(1, 2), vec![1.0, 0.0,])),
        (k::Tensor::from_vec(k::Vec2(1, 2), vec![1.0, 1.0,]), k::Tensor::from_vec(k::Vec2(1, 2), vec![0.0, 1.0,])),
    ];

    // variable_context.set(input_x.get_id(), training_set.0.clone());
    // variable_context.set(target_y.get_id(), training_set.1.clone());
    // println!("\ninput x");
    // let final_test = k::execute(input_x.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nweight w 1");
    // let final_test = k::execute(w.clone(), &state_context, &variable_context);
    // for i in 0..2 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\ndot");
    // let final_test = k::execute(dot.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nweight b 1");
    // let final_test = k::execute(b.clone(), &state_context, &variable_context);
    // for i in 0..1 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nadd");
    // let final_test = k::execute(add.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nrelu");
    // let final_test = k::execute(relu.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\ntarget y");
    // let final_test = k::execute(target_y.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nxentropy");
    // let final_test = k::execute(xentropy.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }

    let print_rate = 4096;

    let mut history = k::Context::<f64>::with_capacity(5 * layers + 4);

    for i in 0..65536 {
        let (ref a, ref b) = training_vec[i % 4];
        variable_context.set(input_x.get_id(), a.clone());
        variable_context.set(target_y.get_id(), b.clone());
        k::train(xentropy2.clone(), &mut state_context, &variable_context, &mut history, -0.1);
        if i % print_rate == 0 {
            variable_context.set(input_x.get_id(), training_set.0.clone());
            variable_context.set(target_y.get_id(), training_set.1.clone());
            println!("\nxentropy2");
            let final_test = k::execute(xentropy2.clone(), &state_context, &variable_context);
            for i in 0..4 {
                println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
            }
        }
    }

    // println!("\ninput x");
    // let final_test = k::execute(input_x.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nweight w 1");
    // let final_test = k::execute(w.clone(), &state_context, &variable_context);
    // for i in 0..2 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\ndot");
    // let final_test = k::execute(dot.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nweight b 1");
    // let final_test = k::execute(b.clone(), &state_context, &variable_context);
    // for i in 0..1 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nadd");
    // let final_test = k::execute(add.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nrelu");
    // let final_test = k::execute(relu.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\ntarget y");
    // let final_test = k::execute(target_y.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nxentropy");
    // let final_test = k::execute(xentropy.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }

    variable_context.set(input_x.get_id(), training_set.0.clone());
    variable_context.set(target_y.get_id(), training_set.1.clone());
    println!("\nxentropy2");
    let final_test = k::execute(xentropy2.clone(), &state_context, &variable_context);
    for i in 0..4 {
        println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    }
}
<commit_msg>xor batching works<commit_after>extern crate ktensor as k;
use std::sync::{Arc};

#[test]
fn xor() {
    // Variables
    let input_x = Arc::new(k::Variable::new("input_x".to_string(), k::Vec2(0, 2)));
    let target_y = Arc::new(k::Variable::new("target_y".to_string(), k::Vec2(0, 2)));

    // Initialize
    let mut variable_context = k::Context::<f64>::with_capacity(2);
    k::variable::init_f64(vec![input_x.clone(), target_y.clone()], &mut variable_context);

    // Graph
    let layers: usize = 2;
    let mut states = Vec::<Arc<k::State>>::with_capacity(2 * layers);
    let mut graph_head: Arc<k::Graph<f64>> = input_x.clone();

    let w = Arc::new(k::State::new(format!("weight_w_{}", 1), k::Vec2(2, 4)));
    let b = Arc::new(k::State::new(format!("weight_b_{}", 1), k::Vec2(1, 4)));

    let dot = Arc::new(k::op::dot::<f64>(format!("layer_{}_dot", 1), graph_head.clone(), w.clone()));
    let add = Arc::new(k::op::add_f64(format!("layer_{}_add", 1), dot.clone(), b.clone()));

    let relu = Arc::new(k::op::relu_f64(format!("layer_{}_relu", 1), add.clone()));

    graph_head = relu.clone();

    states.push(w.clone());
    states.push(b.clone());

    let w2 = Arc::new(k::State::new(format!("weight_w_{}", 2), k::Vec2(4, 2)));
    let b2 = Arc::new(k::State::new(format!("weight_b_{}", 2), k::Vec2(1, 2)));

    let dot2 = Arc::new(k::op::dot::<f64>(format!("layer_{}_dot", 2), graph_head.clone(), w2.clone()));
    let add2 = Arc::new(k::op::add_f64(format!("layer_{}_add", 2), dot2.clone(), b2.clone()));

    let relu2 = Arc::new(k::op::relu_f64(format!("layer_{}_relu", 2), add2.clone()));

    graph_head = relu2.clone();

    states.push(w2.clone());
    states.push(b2.clone());

    let softmax2 = Arc::new(k::op::softmax_f64(format!("layer_{}_softmax", 2), graph_head.clone()));
    let xentropy2 = Arc::new(k::cost::softmax_cross_entropy_f64(format!("layer_{}_xentropy", 2), softmax2.clone(), target_y.clone()));

    // initialize states
    let mut state_context = k::Context::<f64>::with_capacity(2 * layers);
    k::state::init_f64(states, &mut state_context);

    let training_set = (
        k::Tensor::from_vec(k::Vec2(4, 2), vec![
        0.0, 0.0,
        0.0, 1.0,
        1.0, 0.0,
        1.0, 1.0,
        ]),
        k::Tensor::from_vec(k::Vec2(4, 2), vec![
        0.0, 1.0,
        1.0, 0.0,
        1.0, 0.0,
        0.0, 1.0,
        ]),
    );

    let training_vec = vec![
        (k::Tensor::from_vec(k::Vec2(1, 2), vec![0.0, 0.0,]), k::Tensor::from_vec(k::Vec2(1, 2), vec![0.0, 1.0,])),
        (k::Tensor::from_vec(k::Vec2(1, 2), vec![0.0, 1.0,]), k::Tensor::from_vec(k::Vec2(1, 2), vec![1.0, 0.0,])),
        (k::Tensor::from_vec(k::Vec2(1, 2), vec![1.0, 0.0,]), k::Tensor::from_vec(k::Vec2(1, 2), vec![1.0, 0.0,])),
        (k::Tensor::from_vec(k::Vec2(1, 2), vec![1.0, 1.0,]), k::Tensor::from_vec(k::Vec2(1, 2), vec![0.0, 1.0,])),
    ];

    // variable_context.set(input_x.get_id(), training_set.0.clone());
    // variable_context.set(target_y.get_id(), training_set.1.clone());
    // println!("\ninput x");
    // let final_test = k::execute(input_x.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nweight w 1");
    // let final_test = k::execute(w.clone(), &state_context, &variable_context);
    // for i in 0..2 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\ndot");
    // let final_test = k::execute(dot.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nweight b 1");
    // let final_test = k::execute(b.clone(), &state_context, &variable_context);
    // for i in 0..1 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nadd");
    // let final_test = k::execute(add.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nrelu");
    // let final_test = k::execute(relu.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\ntarget y");
    // let final_test = k::execute(target_y.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nxentropy");
    // let final_test = k::execute(xentropy.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }

    let batch = true;
    let print_rate = 4096;

    let mut history = k::Context::<f64>::with_capacity(5 * layers + 4);

    if batch {
        variable_context.set(input_x.get_id(), training_set.0.clone());
        variable_context.set(target_y.get_id(), training_set.1.clone());
    }
    for i in 0..16384 {
        let (ref a, ref b) = training_vec[i % 4];
        if !batch {
            variable_context.set(input_x.get_id(), a.clone());
            variable_context.set(target_y.get_id(), b.clone());
        }
        k::train(xentropy2.clone(), &mut state_context, &variable_context, &mut history, -0.1);
        if i % print_rate == 0 {
            variable_context.set(input_x.get_id(), training_set.0.clone());
            variable_context.set(target_y.get_id(), training_set.1.clone());
            println!("\nxentropy2");
            let final_test = k::execute(xentropy2.clone(), &state_context, &variable_context);
            for i in 0..4 {
                println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
            }
        }
    }

    // println!("\ninput x");
    // let final_test = k::execute(input_x.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nweight w 1");
    // let final_test = k::execute(w.clone(), &state_context, &variable_context);
    // for i in 0..2 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\ndot");
    // let final_test = k::execute(dot.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nweight b 1");
    // let final_test = k::execute(b.clone(), &state_context, &variable_context);
    // for i in 0..1 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nadd");
    // let final_test = k::execute(add.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nrelu");
    // let final_test = k::execute(relu.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\ntarget y");
    // let final_test = k::execute(target_y.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }
    // println!("\nxentropy");
    // let final_test = k::execute(xentropy.clone(), &state_context, &variable_context);
    // for i in 0..4 {
    //     println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    // }

    variable_context.set(input_x.get_id(), training_set.0.clone());
    variable_context.set(target_y.get_id(), training_set.1.clone());
    println!("\nxentropy2");
    let final_test = k::execute(xentropy2.clone(), &state_context, &variable_context);
    for i in 0..4 {
        println!("{} {}", final_test.get(k::Vec2(i, 0)), final_test.get(k::Vec2(i, 1)));
    }
}
<|endoftext|>


<commit_before>// http://dev.w3.org/csswg/css3-syntax/#tokenization
//
// The output of the tokenization step is a series of zero or more
// of the following tokens:
// ident, function, at-keyword, hash, string, bad-string, url, bad-url,
// delim, number, percentage, dimension, unicode-range, whitespace, comment,
// cdo, cdc, colon, semicolon, [, ], (, ), {, }.
//
// ident, function, at-keyword, hash, string, and url tokens
// have a value composed of zero or more characters.
// Delim tokens have a value composed of a single character.
// Number, percentage, and dimension tokens have a representation
// composed of 1 or more character, a numeric value,
// and a type flag set to either "integer" or "number".
// The type flag defaults to "integer" if not otherwise set.
// Dimension tokens additionally have a unit
// composed of one or more characters.
// Unicode-range tokens have a range of characters.

use cssparser;

const MAX_UNICODE: uint = 0x10FFFF;

#[deriving_eq]
enum NumericValue {
    Integer(int),
    // The spec calls this "number".
    // Use "float" instead to reduce term overloading with "number token".
    Float(float),
}
// TODO: add a NumberValue.as_float() method.

#[deriving_eq]
enum Token {
    Ident(~str),
    Function(~str),
    AtKeyword(~str),
    Hash(~str),
    String(~str),
    BadString,
    URL(~str),
    BadURL,
    Delim(char),
    Number(NumericValue, ~str),  // value, representation
    Percentage(NumericValue, ~str),  // value, representation
    Dimension(NumericValue, ~str, ~str),  // value, representation, unit
    UnicodeRange(char, char),  // start, end. XXX what about empty ranges?
    WhiteSpace,
    Comment,
    CDO,  // <!--
    CDC,  // -->
    Colon,  // ,
    Semicolon,  // ;
    OpenBraket, // [
    OpenParen, // (
    OpenBrace, // {
    CloseBraket, // ]
    CloseParen, // )
    CloseBrace, // }
}

struct State {
    input: ~str,
    length: uint,
    mut position: uint,
    mut errors: ~[~str]
}

fn is_eof(state: &State) -> bool {
    state.position >= state.length
}

fn current_char(state: &State) -> char {
    str::char_at(state.input, state.position)
}

fn consume_char(state: &State) -> char {
    let range = str::char_range_at(state.input, state.position);
    state.position = range.next;
    range.ch
}

fn consume_whitespace(state: &State) -> Token {
    while !is_eof(state) {
        match current_char(state) {
            '\t' | '\n' | '\x0C' | ' ' => state.position += 1,
            _ => break,
        }
    }
    WhiteSpace
}

fn char_from_hex(hex: &[char]) -> char {
    let mut value = 0u;
    for hex.each |cc| {
        let c = *cc;
        value = value * 16 + c as uint - match c {
            '0'..'9' => '0' as uint,
            'A'..'F' => 'A' as uint - 10,
            'a'..'f' => 'a' as uint - 10,
            _ => fail
        }
    }
    if value == 0 || value > MAX_UNICODE {
        '\uFFFD'  // Replacement character
    } else {
        value as char
    }
}

// 3.3.27. Consume an escaped character
// Assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed
// and that the next input character has already been verified
// to not be a newline or EOF.
fn consume_escape(state: &State) -> char {
    let c = consume_char(state);
    match c {
        '0'..'9' | 'A'..'F' | 'a'..'f' => {
            let mut hex = ~[c];
            while hex.len() < 6 && !is_eof(state) {
                let c = current_char(state);
                match c {
                    '0'..'9' | 'A'..'F' | 'a'..'f' => {
                        hex.push(c); state.position += 1 },
                    _ => break
                }
            }
            if !is_eof(state) {
                match current_char(state) {
                    '\t' | '\n' | '\x0C' | ' ' => state.position += 1,
                    _ => ()
                }
            }
            char_from_hex(hex)
        },
        c => c
    }
}

// 3.3.5. Double-quote-string state
// 3.3.6. Single-quote-string state
fn consume_quoted_string(state: &State, single_quote: bool) -> Token {
    let mut string: ~str = ~"";
    loop {
        if is_eof(state) {
            state.errors.push(~"EOF in quoted string");
            return String(string);
        }
        match consume_char(state) {
            '"' if !single_quote => return String(string),
            '\'' if single_quote => return String(string),
            '\n' | '\x0C' => {
                state.errors.push(~"Newline in quoted string");
                return BadString
            },
            '\\' => {
                if is_eof(state) {
                    state.errors.push(~"EOF in a quoted string");
                    return BadString
                }
                match current_char(state) {
                    // Consume quoted newline
                    '\n' | '\x0C' => state.position += 1,
                    _ =>  str::push_char(&mut string, consume_escape(state))
                }
            }
            c => str::push_char(&mut string, c),
        }
    }
}

// 3.3.9. Comment state
fn consume_comment(state: &State) -> Token {
    state.position += 1;  // consume the * in /*
    match str::find_str_from(state.input, "*/", state.position) {
        Some(end_position) => state.position = end_position + 2,
        None => {
            state.errors.push(~"EOF in comment");
            state.position = state.input.len();
        }
    }
    Comment
}

// http://dev.w3.org/csswg/css3-syntax/#tokenization
fn tokenize(input: &str//, transform_function_whitespace: bool,
//            quirks_mode: bool
            ) -> {tokens: ~[Token], parse_errors: ~[~str]} {
    let input = cssparser::preprocess(input);
    let state = &State {
        input: input, length: input.len(),
        position: 0, errors: ~[] };
    let mut tokens: ~[Token] = ~[];

    // 3.3.4. Data state
    while !is_eof(state) {
        tokens.push(match consume_char(state) {
            '\t' | '\n' | '\x0C' | ' ' => consume_whitespace(state),
            '"' => consume_quoted_string(state, false),
            '\'' => consume_quoted_string(state, true),
            '/' if !is_eof(state) && current_char(state) == '*'
                => consume_comment(state),
            ',' => Colon,
            ';' => Semicolon,
            '[' => OpenBraket,
            '(' => OpenParen,
            '{' => OpenBrace,
            ']' => CloseBraket,
            ')' => CloseParen,
            '}' => CloseBrace,
            c => Delim(c),
        })
    }

    // Work around `error: moving out of mutable field`
    // TODO: find a cleaner way.
    let mut errors: ~[~str] = ~[];
    errors <-> state.errors;
    {tokens: tokens, parse_errors: errors}
}

#[test]
fn test_tokenizer() {
    fn assert_tokens(input: &str, expected_tokens: &[Token],
                     expected_errors: &[~str]) {
        let result = tokenize(input//, false, false
        );
        let tokens: &[Token] = result.tokens;
        let parse_errors: &[~str] = result.parse_errors;
        if tokens != expected_tokens {
            fail fmt!("%? != %?", tokens, expected_tokens);
        }
        if parse_errors != expected_errors {
            fail fmt!("%? != %?", parse_errors, expected_errors);
        }
    }
    assert_tokens("", [], []);
    assert_tokens("?/", [Delim('?'), Delim('/')], []);
    assert_tokens("?/* Li/*psum… */", [Delim('?'), Comment], []);
    assert_tokens("?/* Li/*psum… *//", [Delim('?'), Comment, Delim('/')], []);
    assert_tokens("?/* Lipsum", [Delim('?'), Comment], [~"EOF in comment"]);
    assert_tokens("?/*", [Delim('?'), Comment], [~"EOF in comment"]);
    assert_tokens("[?}{)",
        [OpenBraket, Delim('?'), CloseBrace, OpenBrace, CloseParen], []);
    assert_tokens("(\n \t'Lore\\6d \"ipsu\\6D'",
        [OpenParen, WhiteSpace, String(~"Lorem\"ipsum")], []);
    assert_tokens("\"0\\0000000\"", [String(~"0\uFFFD0")], []);
    assert_tokens("\"0\\000000 0\"", [String(~"0\uFFFD0")], []);
    assert_tokens("'z\n'a", [BadString, String(~"a")],
        [~"Newline in quoted string", ~"EOF in quoted string"]);
}
<commit_msg>Add ident and function tokens.<commit_after>// http://dev.w3.org/csswg/css3-syntax/#tokenization
//
// The output of the tokenization step is a series of zero or more
// of the following tokens:
// ident, function, at-keyword, hash, string, bad-string, url, bad-url,
// delim, number, percentage, dimension, unicode-range, whitespace, comment,
// cdo, cdc, colon, semicolon, [, ], (, ), {, }.
//
// ident, function, at-keyword, hash, string, and url tokens
// have a value composed of zero or more characters.
// Delim tokens have a value composed of a single character.
// Number, percentage, and dimension tokens have a representation
// composed of 1 or more character, a numeric value,
// and a type flag set to either "integer" or "number".
// The type flag defaults to "integer" if not otherwise set.
// Dimension tokens additionally have a unit
// composed of one or more characters.
// Unicode-range tokens have a range of characters.

use cssparser;

const MAX_UNICODE: uint = 0x10FFFF;

#[deriving_eq]
enum NumericValue {
    Integer(int),
    // The spec calls this "number".
    // Use "float" instead to reduce term overloading with "number token".
    Float(float),
}
// TODO: add a NumberValue.as_float() method.

#[deriving_eq]
enum Token {
    Ident(~str),
    Function(~str),
    AtKeyword(~str),
    Hash(~str),
    String(~str),
    BadString,
    URL(~str),
    BadURL,
    Delim(char),
    Number(NumericValue, ~str),  // value, representation
    Percentage(NumericValue, ~str),  // value, representation
    Dimension(NumericValue, ~str, ~str),  // value, representation, unit
    UnicodeRange(char, char),  // start, end. XXX what about empty ranges?
    WhiteSpace,
    Comment,
    CDO,  // <!--
    CDC,  // -->
    Colon,  // ,
    Semicolon,  // ;
    OpenBraket, // [
    OpenParen, // (
    OpenBrace, // {
    CloseBraket, // ]
    CloseParen, // )
    CloseBrace, // }
}

struct State {
    input: ~str,
    length: uint,
    transform_function_whitespace: bool,
    quirks_mode: bool,
    mut position: uint,
    mut errors: ~[~str]
}

fn is_eof(state: &State) -> bool {
    state.position >= state.length
}

fn current_char(state: &State) -> char {
    str::char_at(state.input, state.position)
}

fn consume_char(state: &State) -> char {
    let range = str::char_range_at(state.input, state.position);
    state.position = range.next;
    range.ch
}

fn consume_whitespace(state: &State) -> Token {
    while !is_eof(state) {
        match current_char(state) {
            '\t' | '\n' | '\x0C' | ' ' => state.position += 1,
            _ => break,
        }
    }
    WhiteSpace
}

fn char_from_hex(hex: &[char]) -> char {
    let mut value = 0u;
    for hex.each |cc| {
        let c = *cc;
        value = value * 16 + c as uint - match c {
            '0'..'9' => '0' as uint,
            'A'..'F' => 'A' as uint - 10,
            'a'..'f' => 'a' as uint - 10,
            _ => fail
        }
    }
    if value == 0 || value > MAX_UNICODE {
        '\uFFFD'  // Replacement character
    } else {
        value as char
    }
}

// 3.3.27. Consume an escaped character
// Assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed
// and that the next input character has already been verified
// to not be a newline or EOF.
fn consume_escape(state: &State) -> char {
    let c = consume_char(state);
    match c {
        '0'..'9' | 'A'..'F' | 'a'..'f' => {
            let mut hex = ~[c];
            while hex.len() < 6 && !is_eof(state) {
                let c = current_char(state);
                match c {
                    '0'..'9' | 'A'..'F' | 'a'..'f' => {
                        hex.push(c); state.position += 1 },
                    _ => break
                }
            }
            if !is_eof(state) {
                match current_char(state) {
                    '\t' | '\n' | '\x0C' | ' ' => state.position += 1,
                    _ => ()
                }
            }
            char_from_hex(hex)
        },
        c => c
    }
}

// 3.3.5. Double-quote-string state
// 3.3.6. Single-quote-string state
fn consume_quoted_string(state: &State, single_quote: bool) -> Token {
    let mut string: ~str = ~"";
    loop {
        if is_eof(state) {
            state.errors.push(~"EOF in quoted string");
            return String(string);
        }
        match consume_char(state) {
            '"' if !single_quote => return String(string),
            '\'' if single_quote => return String(string),
            '\n' | '\x0C' => {
                state.errors.push(~"Newline in quoted string");
                return BadString
            },
            '\\' => {
                if is_eof(state) {
                    state.errors.push(~"EOF in quoted string");
                    return BadString
                }
                match current_char(state) {
                    // Consume quoted newline
                    '\n' | '\x0C' => state.position += 1,
                    _ =>  str::push_char(&mut string, consume_escape(state))
                }
            }
            c => str::push_char(&mut string, c),
        }
    }
}

// 3.3.9. Comment state
fn consume_comment(state: &State) -> Token {
    state.position += 1;  // consume the * in /*
    match str::find_str_from(state.input, "*/", state.position) {
        Some(end_position) => state.position = end_position + 2,
        None => {
            state.errors.push(~"EOF in comment");
            state.position = state.input.len();
        }
    }
    Comment
}

// 3.3.12. Ident state
// 3.3.13. Ident-rest state
fn consume_ident(state: &State, initial_char: char) -> Token {
    let mut string = str::from_char(initial_char);
    while !is_eof(state) {
        let c = current_char(state);
        let cc = match c {
            'a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '-'  => {
                state.position += 1; c },
            _ if c >= '\xA0' => consume_char(state),  // Non-ASCII
            '\\' => {
                state.position += 1;
                if is_eof(state) { state.position -= 1; break }
                match current_char(state) {
                    '\n' | '\x0C' => { state.position -= 1; break },
                    _ => consume_escape(state)
                }
            },
            '\t' | '\n' | '\x0C' | ' ' if state.transform_function_whitespace
            => {
                state.position += 1;
                return handle_transform_function_whitespace(state, string)
            }
            '(' => {
                state.position += 1;
                // TODO: URLs
                return Function(string)
            },
            _ => break
        };
        str::push_char(&mut string, cc)
    }
    Ident(string)
}

// 3.3.14. Transform-function-whitespace state
fn handle_transform_function_whitespace(state: &State, string: ~str) -> Token {
    while !is_eof(state) {
        match current_char(state) {
            '\t' | '\n' | '\x0C' | ' ' => state.position += 1,
            '(' => { state.position += 1; return Function(string) }
            _ => break,
        }
    }
    // XXX I think the spec is wrong here.
    // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0266.html
    // Go back for one whitespace character.
    state.position -= 1;
    return Ident(string)
}

// http://dev.w3.org/csswg/css3-syntax/#tokenization
fn tokenize(input: &str, transform_function_whitespace: bool,
            quirks_mode: bool) -> {tokens: ~[Token], parse_errors: ~[~str]} {
    let input = cssparser::preprocess(input);
    let state = &State {
        input: input, length: input.len(), quirks_mode: quirks_mode,
        transform_function_whitespace: transform_function_whitespace,
        position: 0, errors: ~[] };
    let mut tokens: ~[Token] = ~[];

    // 3.3.4. Data state
    while !is_eof(state) {
        let c = consume_char(state);
        tokens.push(match c {
            '\t' | '\n' | '\x0C' | ' ' => consume_whitespace(state),
            '"' => consume_quoted_string(state, false),
            '\'' => consume_quoted_string(state, true),
            '/' if !is_eof(state) && current_char(state) == '*'
                => consume_comment(state),
            ',' => Colon,
            ';' => Semicolon,
            '[' => OpenBraket,
            '(' => OpenParen,
            '{' => OpenBrace,
            ']' => CloseBraket,
            ')' => CloseParen,
            '}' => CloseBrace,
            'a'..'z' | 'A'..'Z' | '_' => consume_ident(state, c),
            c if c >= '\xA0' => consume_ident(state, c),  // Non-ASCII
            _ => Delim(c),
        })
    }

    // Work around `error: moving out of mutable field`
    // TODO: find a cleaner way.
    let mut errors: ~[~str] = ~[];
    errors <-> state.errors;
    {tokens: tokens, parse_errors: errors}
}

#[test]
fn test_tokenizer() {

    fn assert_tokens(input: &str, expected_tokens: &[Token],
                     expected_errors: &[~str]) {
        assert_tokens_flags(
            input, false, false, expected_tokens, expected_errors)
    }

    fn assert_tokens_flags(
            input: &str,
            transform_function_whitespace: bool, quirks_mode: bool,
            expected_tokens: &[Token], expected_errors: &[~str]) {
        let result = tokenize(
            input, transform_function_whitespace, quirks_mode);
        let tokens: &[Token] = result.tokens;
        let parse_errors: &[~str] = result.parse_errors;
        if tokens != expected_tokens {
            fail fmt!("%? != %?", tokens, expected_tokens);
        }
        if parse_errors != expected_errors {
            fail fmt!("%? != %?", parse_errors, expected_errors);
        }
    }
    assert_tokens("", [], []);
    assert_tokens("?/", [Delim('?'), Delim('/')], []);
    assert_tokens("?/* Li/*psum… */", [Delim('?'), Comment], []);
    assert_tokens("?/* Li/*psum… *//", [Delim('?'), Comment, Delim('/')], []);
    assert_tokens("?/* Lipsum", [Delim('?'), Comment], [~"EOF in comment"]);
    assert_tokens("?/*", [Delim('?'), Comment], [~"EOF in comment"]);
    assert_tokens("[?}{)",
        [OpenBraket, Delim('?'), CloseBrace, OpenBrace, CloseParen], []);

    assert_tokens("(\n \t'Lore\\6d \"ipsu\\6D'",
        [OpenParen, WhiteSpace, String(~"Lorem\"ipsum")], []);
    assert_tokens("'\\''", [String(~"'")], []);
    assert_tokens("\"\\\"\"", [String(~"\"")], []);
    assert_tokens("\"\\\"", [String(~"\"")], [~"EOF in quoted string"]);
    assert_tokens("'\\", [BadString], [~"EOF in quoted string"]);
    assert_tokens("\"0\\0000000\"", [String(~"0\uFFFD0")], []);
    assert_tokens("\"0\\000000 0\"", [String(~"0\uFFFD0")], []);
    assert_tokens("'z\n'a", [BadString, String(~"a")],
        [~"Newline in quoted string", ~"EOF in quoted string"]);

    assert_tokens("Lorem\\ ipsu\\6D dolor sit",
        [Ident(~"Lorem ipsumdolor"), WhiteSpace, Ident(~"sit")], []);
    assert_tokens("foo\\", [Ident(~"foo"), Delim('\\')], []);
    assert_tokens("foo\\\nbar",
        [Ident(~"foo"), Delim('\\'), WhiteSpace, Ident(~"bar")], []);
    assert_tokens("func()", [Function(~"func"), CloseParen], []);
    assert_tokens("func ()",
        [Ident(~"func"), WhiteSpace, OpenParen, CloseParen], []);
    assert_tokens_flags("func ()", true, false,
        [Function(~"func"), CloseParen], []);
}
<|endoftext|>