Skip to content

Commit 5415b43

Browse files
authored
Add test suite (#15)
* Add test suite Minor changes to parsing system were required, now CWD is not changed, instead parser is passed root prefix that is later stripped. * Remove unnecessary comment
1 parent 1c027b3 commit 5415b43

File tree

10 files changed

+186
-16
lines changed

10 files changed

+186
-16
lines changed

.github/workflows/rust.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Rust
2+
3+
on:
4+
push:
5+
branches: ["master"]
6+
pull_request:
7+
branches: ["master"]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
- name: Build
19+
run: cargo build --verbose
20+
- name: Run tests
21+
run: cargo test --verbose

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
/target
2-
tests
32
output.txt
4-
**/*.c
53
**/*.o
64
**/*.out

Cargo.lock

Lines changed: 75 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ cranelift-module = "0.125.3"
1313
cranelift-object = "0.125.3"
1414
lalrpop-util = { version = "0.22.2", features = ["lexer", "unicode"] }
1515

16+
[dev-dependencies]
17+
assert_cmd = "2.1.1"
1618

1719
[build-dependencies]
1820
lalrpop = "0.22.2"

src/driver.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::process::exit;
2+
13
use crate::{
24
Cli, codegen, core,
35
error::{InternalError, ariadne_renderer::AriadneRenderer, context::Context},
@@ -10,7 +12,7 @@ use crate::{
1012
pub fn run(config: Cli) -> Result<(), InternalError> {
1113
let mut ctx = Context::init(Box::new(AriadneRenderer::new()));
1214

13-
let prog = parse_project(&mut ctx)?;
15+
let prog = parse_project(&config.dir, &mut ctx)?;
1416

1517
if config.print_input_ast {
1618
println!("{:#?}", prog);
@@ -28,7 +30,7 @@ pub fn run(config: Cli) -> Result<(), InternalError> {
2830

2931
if error_count != 0 {
3032
println!("{} errors occurred, compilation aborted.", error_count);
31-
return Ok(());
33+
exit(1)
3234
}
3335

3436
if config.typecheck_only {

src/main.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use std::path::PathBuf;
22

33
use clap::Parser;
44

5+
use crate::error::InternalError;
6+
57
mod codegen;
68
mod common;
79
mod core;
@@ -36,10 +38,7 @@ pub struct Cli {
3638
}
3739

3840
/// Entry point, parses command line arguments and starts the compiler pipeline.
39-
pub fn main() {
41+
pub fn main() -> Result<(), InternalError> {
4042
let cli = Cli::parse();
41-
std::env::set_current_dir(&cli.dir).unwrap();
42-
if let Err(e) = driver::run(cli) {
43-
eprintln!("Internal error: {:#?}", e);
44-
}
43+
driver::run(cli)
4544
}

src/parser/mod.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use std::{
2-
collections::BTreeMap, fs::read_to_string, hint::unreachable_unchecked, path::PathBuf,
2+
collections::BTreeMap,
3+
fs::read_to_string,
4+
hint::unreachable_unchecked,
5+
path::{Path, PathBuf},
36
sync::Arc,
47
};
58

@@ -13,14 +16,14 @@ pub mod ast;
1316
lalrpop_util::lalrpop_mod!(pub parser, "/parser/parser.rs");
1417

1518
/// Parses the entire `src` directory ignoring files without „mst” extension.
16-
///
17-
/// Expects that CWD is set to project root.
18-
pub fn parse_project(ctx: &mut Context) -> Result<ast::Program, InternalError> {
19-
let mut path = PathBuf::from("src");
19+
pub fn parse_project(root: &Path, ctx: &mut Context) -> Result<ast::Program, InternalError> {
20+
let mut path = PathBuf::from(root);
21+
path.push("src");
2022
let files = get_files(&mut path)?;
2123
let mut file_map = BTreeMap::new();
2224
for file in files {
23-
let module_path = get_module_path(&file)?;
25+
let path = file.strip_prefix(root).unwrap();
26+
let module_path = get_module_path(path)?;
2427
let parsed_file = parse_file(ctx, file)?;
2528
if let Some(module) = parsed_file {
2629
if let Some(_) = file_map.insert(module_path, module) {
@@ -35,7 +38,7 @@ pub fn parse_project(ctx: &mut Context) -> Result<ast::Program, InternalError> {
3538
/// Return the module path of file path.
3639
///
3740
/// Both `bar.mst` and `bar/mod.mst` result in path `[bar]`.
38-
fn get_module_path(path: &PathBuf) -> Result<Vec<String>, InternalError> {
41+
fn get_module_path(path: &Path) -> Result<Vec<String>, InternalError> {
3942
let mut module_path = vec![];
4043
let iter: Vec<&str> = path
4144
.components()

tests/ok/001_functions/src/mod.mst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
pub fn add(lhs: i32, rhs: i32) -> i32 {
3+
@iadd(lhs, rhs)
4+
}
5+
6+
struct S {
7+
a: i32,
8+
b: i32,
9+
}
10+
11+
@extern
12+
@no_mangle
13+
fn main() -> i32 {
14+
let x = 42;
15+
let y = f(x, 13, g(s(), 69));
16+
add(x, y)
17+
}
18+
19+
fn g(x: i32, z: i32) -> i32 {
20+
x
21+
}
22+
23+
fn f(x: i32, y: i32, z: i32) -> i32 {
24+
z
25+
}
26+
27+
fn s() -> i32 {
28+
let s = S {
29+
a = 75,
30+
b = 313,
31+
};
32+
s.a
33+
}

tests/ok/002_modules/src/mod.mst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
mod a {
3+
pub mod b {
4+
pub fn test() -> i32 {
5+
42
6+
}
7+
}
8+
}
9+
10+
@extern
11+
@no_mangle
12+
fn main() -> i32 {
13+
a::b::test()
14+
}

tests/run.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use std::io::Write;
2+
3+
use assert_cmd::cargo::cargo_bin_cmd;
4+
5+
fn test_path(s: &str) {
6+
let output = cargo_bin_cmd!("mustcc").arg(s).output().unwrap();
7+
8+
std::io::stderr()
9+
.write_all(output.stderr.as_slice())
10+
.unwrap();
11+
12+
assert!(output.status.code() == Some(0), "non-zero exit code")
13+
}
14+
15+
#[test]
16+
fn test_001() {
17+
test_path("tests/ok/001_functions")
18+
}
19+
20+
#[test]
21+
fn test_002() {
22+
test_path("tests/ok/002_modules")
23+
}

0 commit comments

Comments
 (0)