Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] tests: simplified declarations #981

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ libc = "*"
regex="*"
rand="*"
tempdir="*"
choose = { path = "tests/choose" }

[[bin]]
name = "uutils"
Expand Down
7 changes: 7 additions & 0 deletions tests/choose/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "choose"
version = "0.1.0"
authors = ["Knight <[email protected]>"]

[lib]
plugin = true
121 changes: 121 additions & 0 deletions tests/choose/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#![feature(plugin_registrar, rustc_private)]

extern crate syntax;
extern crate rustc_plugin;

use syntax::ast;
use syntax::ptr::P;
use syntax::codemap::Span;
use syntax::parse::{self, token};
use syntax::tokenstream::TokenTree;
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
use syntax::ext::build::AstBuilder;
use syntax::errors::FatalError;
use syntax::util::small_vector::SmallVector;
use rustc_plugin::Registry;

use ::std::path::Path;
use ::std::path::PathBuf;

macro_rules! panictry {
($e:expr) => ({
match $e {
Ok(e) => e,
Err(mut e) => {
e.emit();
panic!(FatalError);
}
}
})
}

pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, file: &Path) -> Vec<P<ast::Item>> {
let mut p = parse::new_sub_parser_from_file(cx.parse_sess(), cx.cfg(), file, true, None, sp);
let mut ret = vec![];
while p.token != token::Eof {
match panictry!(p.parse_item()) {
Some(item) => ret.push(item),
None => {
panic!(p.diagnostic().span_fatal(p.span,
&format!("expected item, found `{}`", p.this_token_to_string())))
}
}
}
ret
}

fn intern(s: &str) -> token::InternedString {
token::intern_and_get_ident(s)
}

fn choose(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> {
let mut parser = cx.new_parser_from_tts(args);
let mut test_mods = SmallVector::zero();
let cfg_str = intern("cfg");
let feat_str = intern("feature");
while !parser.eat(&token::Eof) {
if let Ok(s) = parser.parse_ident() {
let unix_only;
match s.to_string().as_str() {
"unix" => unix_only = true,
"generic" => unix_only = false,
_ => {
cx.span_err(sp, "only `unix` and `generic` are supported now");
return DummyResult::any(sp);
}
}
parser.eat(&token::FatArrow);
parser.eat(&token::OpenDelim(token::Brace));
while !parser.eat(&token::CloseDelim(token::Brace)) {
match parser.parse_ident() {
Ok(s) => {
let mod_name = s.to_string();
let mut attrs = vec![cx.attribute(sp,
cx.meta_list(sp,
cfg_str.clone(),
vec![cx.meta_name_value(sp,
feat_str.clone(),
ast::LitKind::Str(intern(mod_name.trim_left_matches("test_")), ast::StrStyle::Cooked))]))];

if unix_only {
attrs.push(cx.attribute(sp,
cx.meta_list(sp,
cfg_str.clone(),
vec![cx.meta_word(sp, intern("unix"))])));
}

let mut mod_path = PathBuf::from(&cx.codemap().span_to_filename(sp));
mod_path.set_file_name(mod_name.as_str());
mod_path.set_extension("rs");
test_mods.push(P(ast::Item {
ident: cx.ident_of(mod_name.as_str()),
attrs: attrs,
id: ast::DUMMY_NODE_ID,
node: ast::ItemKind::Mod(ast::Mod {
inner: sp,
items: expand_include(cx, sp, &mod_path),
}),
vis: ast::Visibility::Inherited,
span: sp,
}));
}
_ => {
cx.span_err(sp, "expect a single identifier");
return DummyResult::any(sp);
}
}
parser.eat(&token::Semi);
parser.eat(&token::Comma);
}
} else {
cx.span_err(sp, "expect a single identifier");
return DummyResult::any(sp);
}
}
MacEager::items(test_mods)
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_macro("choose", choose);
}
151 changes: 67 additions & 84 deletions tests/tests.rs
Original file line number Diff line number Diff line change
@@ -1,88 +1,71 @@
#![cfg_attr(test, feature(plugin))]
#![cfg_attr(test, plugin(choose))]

#[macro_use]
mod common;

// For conditional compilation
macro_rules! unix_only {
($($fea:expr, $m:ident);+) => {
$(
#[cfg(unix)]
#[cfg(feature = $fea)]
mod $m;
)+
};
}
unix_only! {
"chmod", test_chmod;
"chown", test_chown;
"chgrp", test_chgrp;
"install", test_install;
"mv", test_mv;
"pathchk", test_pathchk;
"pinky", test_pinky;
"stdbuf", test_stdbuf;
"touch", test_touch;
"unlink", test_unlink;
"who", test_who;
// Be aware of the trailing semicolon after the last item
"stat", test_stat
}


macro_rules! generic {
($($fea:expr, $m:ident);+) => {
$(
#[cfg(feature = $fea)]
mod $m;
)+
};
}
generic! {
"base32", test_base32;
"base64", test_base64;
"basename", test_basename;
"cat", test_cat;
"cksum", test_cksum;
"comm", test_comm;
"cp", test_cp;
"cut", test_cut;
"dircolors", test_dircolors;
"dirname", test_dirname;
"echo", test_echo;
"env", test_env;
"expr", test_expr;
"factor", test_factor;
"false", test_false;
"fold", test_fold;
"hashsum", test_hashsum;
"head", test_head;
"link", test_link;
"ln", test_ln;
"ls", test_ls;
"mkdir", test_mkdir;
"mktemp", test_mktemp;
"nl", test_nl;
"od", test_od;
"paste", test_paste;
"printf", test_printf;
"ptx", test_ptx;
"pwd", test_pwd;
"readlink", test_readlink;
"realpath", test_realpath;
"rm", test_rm;
"rmdir", test_rmdir;
"seq", test_seq;
"sort", test_sort;
"split", test_split;
"sum", test_sum;
"tac", test_tac;
"tail", test_tail;
"test", test_test;
"tr", test_tr;
"true", test_true;
"truncate", test_truncate;
"tsort", test_tsort;
"unexpand", test_unexpand;
"uniq", test_uniq;
// Be aware of the trailing semicolon after the last item
"wc", test_wc
choose! {
unix => {
test_chmod
test_chown
test_chgrp
test_install
test_mv
test_pathchk
test_pinky
test_stdbuf
test_touch
test_unlink
test_who
test_stat
}
generic => {
test_base32
test_base64
test_basename
test_cat
test_cksum
test_comm
test_cp
test_cut
test_dircolors
test_dirname
test_echo
test_env
test_expr
test_factor
test_false
test_fold
test_hashsum
test_head
test_link
test_ln
test_ls
test_mkdir
test_mktemp
test_nl
test_od
test_paste
test_printf
test_ptx
test_pwd
test_readlink
test_realpath
test_rm
test_rmdir
test_seq
test_sort
test_split
test_sum
test_tac
test_tail
test_test
test_tr
test_true
test_truncate
test_tsort
test_unexpand
test_uniq
test_wc
}
}