Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist
View example.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#[cfg(test)]
mod test {
use hamcrest::{assert_that, is, equal_to};
 
describe!(
before_each {
let value = true;
}
 
it "includes all the statements from before_each scope" {
assert_that(value, is(equal_to(true)));
}
it "can have multiple blocks" {
assert!(true);
}
)
}
View example.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
 
#![crate_name="shiny"]
#![crate_type="dylib"]
#![feature(plugin_registrar, quote, managed_boxes)]
 
extern crate rustc;
extern crate serialize;
extern crate syntax;
 
use rustc::plugin::Registry;
use std::gc::{Gc, GC};
use syntax::ast;
use syntax::codemap::DUMMY_SP;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, MacResult};
use syntax::ext::build::AstBuilder;
use syntax::util::small_vector::SmallVector;
use syntax::parse::tts_to_parser;
use syntax::parse::token;
use syntax::abi;
use syntax::ast_util::empty_generics;
 
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_macro("describe", macro_describe);
}
 
pub fn macro_describe(cx: &mut ExtCtxt, _: Span, tts: &[ast::TokenTree])
-> Box<MacResult> {
let sess = cx.parse_sess();
let ttsvec = tts.iter().map(|x| (*x).clone()).collect();
 
let mut parser = tts_to_parser(sess, ttsvec, cx.cfg());
 
let mut before_block = None;
let mut test_blocks = vec!();
 
loop {
if parser.token == token::EOF {
break;
}
 
let ident = parser.parse_ident();
match ident.as_str() {
"before_each" => {
if before_block.is_some() {
fail!("only one before_each block is allowed");
}
before_block = Some(parser.parse_block());
},
"it" => {
let (name, _) = parser.parse_str();
let block = parser.parse_block();
test_blocks.push((name.get().to_string(), block));
}
_ => fail!(),
}
}
 
let mut funcs = vec!();
 
for &(ref name, block) in test_blocks.iter() {
let body = if before_block.is_none() {
block
} else {
let before = before_block.unwrap();
 
box(GC) ast::Block {
view_items: before.view_items + block.view_items,
stmts: before.stmts + block.stmts,
..block.deref().clone()
}
};
 
let attr_test = cx.attribute(DUMMY_SP, cx.meta_word(
DUMMY_SP, token::InternedString::new("test")));
let attrs = vec!(attr_test);
 
let func = box(GC) ast::Item {
ident: cx.ident_of(name.replace(" ", "_").as_slice()),
attrs: attrs,
id: ast::DUMMY_NODE_ID,
node: ast::ItemFn(
cx.fn_decl(Vec::new(), cx.ty_nil()),
ast::NormalFn,
abi::Rust,
empty_generics(),
body),
vis: ast::Inherited,
span: DUMMY_SP,
};
funcs.push(func);
}
 
MacItems::new(funcs)
}
 
pub struct MacItems {
items: Vec<Gc<ast::Item>>
}
 
impl MacItems {
pub fn new(items: Vec<Gc<ast::Item>>) -> Box<MacResult> {
box MacItems { items: items } as Box<MacResult>
}
}
impl MacResult for MacItems {
fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
Some(SmallVector::many(self.items.clone()))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.