Repository: gluon-lang/gluon
Pull request #313 (2017-07-09 11:17:34)

refactor: Cleanup the bash scripts/release.sh
* Remove unused test scripts
* Hide remaining scripts in a directory
* Add travis.sh so "full tests" can be run locally


Patch:
diff --git a/.travis.yml b/.travis.yml
index 269946cd..488d6cbd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,14 +18,7 @@ before_script:
   pip install 'travis-cargo<0.2' --user &&
   export PATH=$HOME/Library/Python/2.7/bin:$HOME/.local/bin:$PATH
 script:
-- |
-  sh ./test-no-skeptic.sh &&
-  travis-cargo --only nightly test -- --features "test nightly" -p gluon compile_test &&
-  travis-cargo --only nightly bench &&
-  travis-cargo --only stable build -- --all --no-default-features
-env:
-  global:
-  - TRAVIS_CARGO_NIGHTLY_FEATURE="nightly"
+- ./scripts/travis.sh
 notifications:
   webhooks:
     urls:
diff --git a/Cargo.toml b/Cargo.toml
index 2137e4e1..bf466221 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -43,6 +43,7 @@ skeptic = { version = "0.6", optional = true }
 skeptic = { version = "0.6", optional = true }
 
 [dev-dependencies]
+bencher = "0.1.2"
 collect-mac = "0.1.0"
 env_logger = "0.3.4"
 
@@ -57,3 +58,16 @@ default = ["regex"]
 
 test = ["gluon_vm/test", "gluon_check/test", "gluon_parser/test"]
 nightly = ["compiletest_rs"]
+
+
+[[bench]]
+name = "check"
+harness = false
+
+[[bench]]
+name = "function_call"
+harness = false
+
+[[bench]]
+name = "parser"
+harness = false
diff --git a/base/src/pretty_print.rs b/base/src/pretty_print.rs
index 9341d276..df8edbb6 100644
--- a/base/src/pretty_print.rs
+++ b/base/src/pretty_print.rs
@@ -264,7 +264,7 @@ impl<'a> ExprPrinter<'a> {
     where
         Id: AsRef<str>,
     {
-        self.pretty_expr_with_shebang_line(expr).append(
+        self.pretty_expr_(BytePos::from(0), expr).append(
             self.comments(Span::new(
                 expr.span.end,
                 BytePos::from(self.source.src().len()),
@@ -272,36 +272,6 @@ impl<'a> ExprPrinter<'a> {
         )
     }
 
-    fn find_shebang_line(&'a self) -> Option<&str> {
-        let src = self.source.src();
-        if src.starts_with("#!") {
-            src.lines().next()
-        }
-        else {
-            None
-        }
-    }
-
-    pub fn pretty_expr_with_shebang_line<Id>(
-        &'a self,
-        expr: &'a SpannedExpr<Id>,
-    ) -> DocBuilder<'a, Arena<'a>>
-    where
-        Id: AsRef<str>,
-    {
-        let arena = &self.arena;
-        match self.find_shebang_line() {
-            Some(shebang_line) => { 
-                arena
-                    .text(shebang_line)
-                    .append(
-                        self.pretty_expr_(BytePos::from(shebang_line.len()), expr)
-                    )
-            },
-            None => self.pretty_expr_(BytePos::from(0), expr)
-        }
-    }
-
     pub fn pretty_expr_<Id>(
         &'a self,
         previous_end: BytePos,
diff --git a/benches/check.rs b/benches/check.rs
index 21926b12..c9836e48 100644
--- a/benches/check.rs
+++ b/benches/check.rs
@@ -1,6 +1,6 @@
-#![feature(test)]
+#[macro_use]
+extern crate bencher;
 
-extern crate test;
 
 extern crate gluon_base as base;
 extern crate gluon_parser as parser;
@@ -10,11 +10,12 @@ extern crate gluon;
 use std::fs::File;
 use std::io::Read;
 
+use bencher::{Bencher, black_box};
+
 use gluon::{Compiler, new_vm};
 use gluon::compiler_pipeline::*;
 
-#[bench]
-fn typecheck_prelude(b: &mut ::test::Bencher) {
+fn typecheck_prelude(b: &mut Bencher) {
     let vm = new_vm();
     let mut compiler = Compiler::new();
     let MacroValue { expr } = {
@@ -32,12 +33,11 @@ fn typecheck_prelude(b: &mut ::test::Bencher) {
             println!("{}", err);
             assert!(false);
         }
-        ::test::black_box(result)
+        black_box(result)
     })
 }
 
-#[bench]
-fn clone_prelude(b: &mut ::test::Bencher) {
+fn clone_prelude(b: &mut Bencher) {
     let vm = new_vm();
     let mut compiler = Compiler::new();
     let TypecheckValue { expr, .. } = {
@@ -49,5 +49,8 @@ fn clone_prelude(b: &mut ::test::Bencher) {
         text.typecheck(&mut compiler, &vm, "std.prelude", &text)
             .unwrap_or_else(|err| panic!("{}", err))
     };
-    b.iter(|| ::test::black_box(expr.clone()))
+    b.iter(|| black_box(expr.clone()))
 }
+
+benchmark_group!(check, typecheck_prelude, clone_prelude);
+benchmark_main!(check);
diff --git a/benches/function_call.rs b/benches/function_call.rs
index 9da395c8..4fb5651b 100644
--- a/benches/function_call.rs
+++ b/benches/function_call.rs
@@ -1,16 +1,16 @@
-#![feature(test)]
-
-extern crate test;
+#[macro_use]
+extern crate bencher;
 
 extern crate gluon;
 
+use bencher::{Bencher, black_box};
+
 use gluon::{Compiler, new_vm};
 use gluon::vm::thread::{Status, Thread};
 use gluon::vm::api::{FunctionRef, primitive};
 
 // Benchmarks function calls
-#[bench]
-fn factorial(b: &mut ::test::Bencher) {
+fn factorial(b: &mut Bencher) {
     let vm = new_vm();
     let text = r#"
     let factorial n =
@@ -23,12 +23,11 @@ fn factorial(b: &mut ::test::Bencher) {
     let mut factorial: FunctionRef<fn(i32) -> i32> = vm.get_global("factorial").unwrap();
     b.iter(|| {
         let result = factorial.call(100).unwrap();
-        ::test::black_box(result)
+        black_box(result)
     })
 }
 
-#[bench]
-fn factorial_tail_call(b: &mut ::test::Bencher) {
+fn factorial_tail_call(b: &mut Bencher) {
     let vm = new_vm();
     let text = r#"
     let factorial a n =
@@ -41,12 +40,11 @@ fn factorial_tail_call(b: &mut ::test::Bencher) {
     let mut factorial: FunctionRef<fn(i32) -> i32> = vm.get_global("factorial").unwrap();
     b.iter(|| {
         let result = factorial.call(100).unwrap();
-        ::test::black_box(result)
+        black_box(result)
     })
 }
 
-#[bench]
-fn gluon_rust_boundary_overhead(b: &mut ::test::Bencher) {
+fn gluon_rust_boundary_overhead(b: &mut Bencher) {
     let vm = new_vm();
 
     extern "C" fn test_fn(_: &Thread) -> Status {
@@ -79,6 +77,10 @@ fn gluon_rust_boundary_overhead(b: &mut ::test::Bencher) {
     let mut test: FunctionRef<fn(i32) -> ()> = vm.get_global("test").unwrap();
     b.iter(|| {
         let result = test.call(1000).unwrap();
-        ::test::black_box(result)
+        black_box(result)
     })
 }
+
+benchmark_group!(function_call,
+    factorial, factorial_tail_call, gluon_rust_boundary_overhead);
+benchmark_main!(function_call);
diff --git a/benches/parser.rs b/benches/parser.rs
index 195eb7a7..d80f0824 100644
--- a/benches/parser.rs
+++ b/benches/parser.rs
@@ -1,14 +1,14 @@
-#![feature(test)]
-
-extern crate test;
+#[macro_use]
+extern crate bencher;
 
 extern crate gluon_base as base;
 extern crate gluon_parser as parser;
 
+use bencher::{Bencher, black_box};
+
 use base::symbol::{Symbols, SymbolModule};
 
-#[bench]
-fn prelude(b: &mut ::test::Bencher) {
+fn prelude(b: &mut Bencher) {
     use std::fs::File;
     use std::io::Read;
     let mut text = String::new();
@@ -21,6 +21,9 @@ fn prelude(b: &mut ::test::Bencher) {
         let mut symbols = SymbolModule::new("".into(), &mut symbols);
         let expr = parser::parse_expr(&mut symbols, &text)
             .unwrap_or_else(|err| panic!("{:?}", err));
-        ::test::black_box(expr)
+        black_box(expr)
     })
 }
+
+benchmark_group!(parser, prelude);
+benchmark_main!(parser);
diff --git a/parser/src/grammar.lalrpop b/parser/src/grammar.lalrpop
index 083398fb..283fb997 100644
--- a/parser/src/grammar.lalrpop
+++ b/parser/src/grammar.lalrpop
@@ -21,7 +21,6 @@ extern {
     type Error = Spanned<Error, BytePos>;
 
     enum Token<'input> {
-        "shebang line" => Token::ShebangLine(<&'input str>),
         "identifier" => Token::Identifier(<&'input str>),
         "operator" => Token::Operator(<&'input str>),
         "string literal" => Token::StringLiteral(<String>),
@@ -505,7 +504,7 @@ SpExpr: SpannedExpr<Id> = {
 };
 
 pub TopExpr: SpannedExpr<Id> = {
-    "shebang line"? <expr: SpExpr> => expr,
+    <expr: SpExpr> => expr,
 };
 
 pub LetOrExpr: Result<SpannedExpr<Id>, ValueBinding<Id>> = {
diff --git a/parser/src/layout.rs b/parser/src/layout.rs
index 0e16108f..b8b4cb08 100644
--- a/parser/src/layout.rs
+++ b/parser/src/layout.rs
@@ -173,7 +173,6 @@ where
         loop {
             // Retrieve the current indentation level if one exists
             let offside = match (&token.value, self.indent_levels.last().cloned()) {
-                (&Token::ShebangLine(_), _) => return Ok(token),
                 (_, Some(offside)) => offside,
                 (&Token::EOF, None) => return Ok(token),
                 (_, None) => {
diff --git a/parser/src/token.rs b/parser/src/token.rs
index 43d5698b..b3f9c00c 100644
--- a/parser/src/token.rs
+++ b/parser/src/token.rs
@@ -7,7 +7,6 @@ use self::Error::*;
 
 #[derive(Clone, PartialEq, Debug)]
 pub enum Token<'input> {
-    ShebangLine(&'input str),
     Identifier(&'input str),
     Operator(&'input str),
 
@@ -55,7 +54,6 @@ impl<'input> fmt::Display for Token<'input> {
         use self::Token::*;
 
         let s = match *self {
-            ShebangLine(_) => "ShebangLine",
             Identifier(_) => "Identifier",
             Operator(_) => "Operator",
             StringLiteral(_) => "StringLiteral",
@@ -366,20 +364,6 @@ impl<'input> Tokenizer<'input> {
         self.error(start, UnterminatedStringLiteral)
     }
 
-    fn shebang_line(&mut self, start: Location) -> Option<SpannedToken<'input>> {
-
-        let (end, line) = self.take_until(start, |ch| ch == '\n');
-        
-        if line.starts_with("#!") {
-            let skip = 2;
-            let result = line[skip..].trim_right();
-            let tok = Token::ShebangLine(result);
-            Some(pos::spanned2(start, end, tok))
-        } else {
-            None
-        }
-    }
-
     fn char_literal(&mut self, start: Location) -> Result<SpannedToken<'input>, SpError> {
         let ch = match self.bump() {
             Some((_, '\\')) => self.escape_code()?,
@@ -489,12 +473,6 @@ impl<'input> Iterator for Tokenizer<'input> {
                         Err(err) => Some(Err(err)),
                     }
                 }
-                '#' if start.absolute == BytePos::from(0) && self.test_lookahead(|ch| ch == '!') => {
-                    match self.shebang_line(start) {
-                        Some(token) => Some(Ok(token)),
-                        None => continue,
-                    }
-                }
 
                 ch if is_ident_start(ch) => Some(Ok(self.identifier(start))),
                 ch if is_digit(ch) || (ch == '-' && self.test_lookahead(is_digit)) => {
@@ -545,19 +523,14 @@ mod test {
 
     fn test(input: &str, expected: Vec<(&str, Token)>) {
         let mut tokenizer = tokenizer(input);
-        let mut count = 0;
-        let length = expected.len();
+
         for (token, (expected_span, expected_tok)) in tokenizer.by_ref().zip(expected.into_iter()) {
-            count += 1;
             println!("{:?}", token);
             let start = loc(expected_span.find("~").unwrap());
             let end = loc(expected_span.rfind("~").unwrap() + 1);
             assert_eq!(Ok(pos::spanned2(start, end, expected_tok)), token);
         }
 
-        assert_eq!(count, length);
-        assert_eq!(true, count > 0);
-
         // Make sure that there is nothing else to consume
         assert_eq!(None, tokenizer.next());
     }
@@ -822,21 +795,4 @@ mod test {
             ],
         );
     }
-
-    #[test]
-    fn shebang_line_token_test() {
-        test(
-            "#!/bin/gluon\nhi /// hellooo/// hi",
-            vec![
-                (r#"~~~~~~~~~~~~                   "#, ShebangLine("/bin/gluon")),
-                (r#"            ~~                 "#, Identifier("hi")),
-                (r#"              ~~~~~~~~~~~~~~~~~"#,
-                    DocComment(Comment {
-                        typ: CommentType::Line,
-                        content: "hellooo/// hi".to_string(),
-                    })
-                ),
-            ],
-        );
-    }
 }
diff --git a/repl/Cargo.toml b/repl/Cargo.toml
index 198b7372..81f991d5 100644
--- a/repl/Cargo.toml
+++ b/repl/Cargo.toml
@@ -11,6 +11,7 @@ documentation = "https://docs.rs/gluon_repl"
 
 [[bin]]
 name = "gluon"
+path = "src/main.rs"
 doc = false
 
 [dependencies]
diff --git a/release.sh b/scripts/release.sh
old mode 100644
new mode 100755
similarity index 95%
rename from release.sh
rename to scripts/release.sh
index 8f8a8527..c88b825a
--- a/release.sh
+++ b/scripts/release.sh
@@ -1,3 +1,5 @@
+#!/bin/sh
+
 (cd base && cargo publish $@) &&
     (cd parser && cargo publish $@) &&
     (cd check && cargo publish $@) &&
diff --git a/scripts/travis.sh b/scripts/travis.sh
new file mode 100755
index 00000000..8eb9de1c
--- /dev/null
+++ b/scripts/travis.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+(
+  export TRAVIS_CARGO_NIGHTLY_FEATURE="nightly";
+  export RUST_BACKTRACE=1;
+  cargo test --features test --all &&
+  travis-cargo --only nightly test -- --features "test nightly" -p gluon compile_test &&
+  cargo check --bench check --features test &&
+  cargo check --bench function_call --features test &&
+  cargo check --bench parser --features test &&
+  travis-cargo --only stable build -- --all --no-default-features
+)
diff --git a/vm/src/api/ser.rs b/vm/src/api/ser.rs
index 1e896c74..7bfaf850 100644
--- a/vm/src/api/ser.rs
+++ b/vm/src/api/ser.rs
@@ -549,7 +549,7 @@ impl<'a, 'vm> ser::SerializeStructVariant for RecordSerializer<'a, 'vm> {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use thread::{RootedThread, RootedValue, ThreadInternal};
+    use thread::{RootedThread, ThreadInternal};
 
     fn to_value<T>(thread: &Thread, value: &T) -> Result<Value>
     where
@@ -560,15 +560,6 @@ mod tests {
         Ok(context.stack.pop())
     }
 
-    fn make_value<'vm, T>(thread: &'vm Thread, value: T) -> RootedValue<&'vm Thread>
-    where
-        T: Pushable<'vm>,
-    {
-        let mut context = thread.context();
-        value.push(thread, &mut context).unwrap();
-        thread.root_value(context.stack.pop())
-    }
-
     #[test]
     fn bool() {
         let thread = RootedThread::new();
diff --git a/vm/src/lib.rs b/vm/src/lib.rs
index 93000139..7f35df01 100644
--- a/vm/src/lib.rs
+++ b/vm/src/lib.rs
@@ -24,9 +24,6 @@ extern crate futures;
 #[cfg(feature = "serde")]
 #[macro_use]
 extern crate serde;
-#[cfg(all(feature = "serde", test))]
-#[macro_use]
-extern crate serde_derive;
 
 #[macro_use]
 extern crate gluon_base as base;


Test patch:
diff --git a/check/tests/row_polymorphism.rs b/check/tests/row_polymorphism.rs
index 3e923049..42b1fdd3 100644
--- a/check/tests/row_polymorphism.rs
+++ b/check/tests/row_polymorphism.rs
@@ -14,14 +14,6 @@ use support::{MockEnv, MockIdentEnv, intern, typ};
 
 mod support;
 
-macro_rules! assert_pass {
-    ($e: expr) => {{
-        if !$e.is_ok() {
-            panic!("assert_pass: {}", $e.unwrap_err());
-        }
-    }};
-}
-
 #[test]
 fn infer_fields() {
     let _ = env_logger::init();
diff --git a/parser/tests/basic.rs b/parser/tests/basic.rs
index 23a6cc7d..8e6dc479 100644
--- a/parser/tests/basic.rs
+++ b/parser/tests/basic.rs
@@ -726,15 +726,3 @@ fn doc_comment_on_record_field() {
         })
     )
 }
-
-#[test]
-fn shebang_at_top_is_ignored() {
-    let _ = ::env_logger::init();
-    let text = r"#!/bin/gluon
-{ Test, x }";
-    let e = parse_new!(text);
-    assert_eq!(
-        e,
-        record_a(vec![("Test".into(), None)], vec![("x".into(), None)])
-    )
-}
diff --git a/parser/tests/pretty_print.rs b/parser/tests/pretty_print.rs
index b4e1c85c..b6f7860b 100644
--- a/parser/tests/pretty_print.rs
+++ b/parser/tests/pretty_print.rs
@@ -146,14 +146,3 @@ x
 "#;
     assert_eq!(&format_expr(expr).unwrap(), expr);
 }
-
-#[test]
-fn preserve_shebang_line() {
-    let expr = r#"#!/bin/gluon
-/* test */
-let x = { field = f /* test */ 123 /* doc */ }
-/* test */
-x
-"#;
-    assert_eq!(&format_expr(expr).unwrap(), expr);
-}
diff --git a/repl/tests/tests.rs b/repl/tests/tests.rs
index d0b80ab0..007fa8de 100644
--- a/repl/tests/tests.rs
+++ b/repl/tests/tests.rs
@@ -15,10 +15,10 @@ fn fmt_repl() {
         .read_to_string(&mut before)
         .unwrap();
 
-    let status = Command::new("gluon")
+    let status = Command::new("../target/debug/gluon")
         .args(&["fmt", source])
         .spawn()
-        .unwrap()
+        .expect("Could not find gluon executable")
         .wait()
         .unwrap();
     assert!(status.success());
diff --git a/version.sh b/scripts/version.sh
old mode 100644
new mode 100755
similarity index 100%
rename from version.sh
rename to scripts/version.sh
diff --git a/test-nightly.sh b/test-nightly.sh
deleted file mode 100644
index f643d127..00000000
--- a/test-nightly.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-cargo test -p gluon_base &&
-    cargo test -p gluon_parser --features test &&
-    cargo test -p gluon_check --features test &&
-    cargo test -p gluon_vm --features test &&
-    cargo test --features "test skeptic nightly" &&
-    (cd c-api && cargo test --features "test skeptic nightly")
diff --git a/test-no-skeptic.sh b/test-no-skeptic.sh
deleted file mode 100644
index 0e642834..00000000
--- a/test-no-skeptic.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-(cd c-api &&
-    cargo test -p gluon_base &&
-    cargo test -p gluon_parser --features test &&
-    cargo test -p gluon_check --features test &&
-    cargo test -p gluon_vm --features test &&
-    cargo test -p gluon --features test &&
-    cargo test --features test)
diff --git a/test.sh b/test.sh
deleted file mode 100644
index f8d68943..00000000
--- a/test.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-(cd c-api &&
-    cargo test -p gluon_base &&
-    cargo test -p gluon_parser --features test &&
-    cargo test -p gluon_check --features test &&
-    cargo test -p gluon_vm --features test &&
-    cargo test -p gluon --features "test skeptic" &&
-    cargo test --features "test skeptic")
diff --git a/tests/support/mod.rs b/tests/support/mod.rs
index c4d704cb..ca905bc4 100644
--- a/tests/support/mod.rs
+++ b/tests/support/mod.rs
@@ -48,6 +48,7 @@ pub fn make_vm() -> RootedThread {
     vm
 }
 
+#[allow(unused_macros)]
 macro_rules! test_expr {
     (prelude $name: ident, $expr: expr, $value: expr) => {
         #[test]