Skip to content

Commit

Permalink
Add test case for procedural macro compilation
Browse files Browse the repository at this point in the history
commit-id:e457ae12
  • Loading branch information
maciektr committed Feb 21, 2024
1 parent ea61895 commit ce35014
Showing 1 changed file with 108 additions and 15 deletions.
123 changes: 108 additions & 15 deletions scarb/tests/build_cairo_plugin.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,120 @@
use assert_fs::fixture::{FileWriteStr, PathChild};
use assert_fs::TempDir;
use indoc::indoc;
use camino::Utf8PathBuf;
use indoc::{formatdoc, indoc};
use snapbox::assert_matches;
use std::collections::HashMap;
use std::path::PathBuf;

use scarb_test_support::command::Scarb;
use scarb_test_support::fsx;
use scarb_test_support::project_builder::ProjectBuilder;

struct CairoPluginProjectBuilder {
project: ProjectBuilder,
src: HashMap<Utf8PathBuf, String>,
}

impl CairoPluginProjectBuilder {
pub fn start() -> Self {
Self {
project: ProjectBuilder::start(),
src: Default::default(),
}
}

pub fn scarb_project(mut self, mutate: impl FnOnce(ProjectBuilder) -> ProjectBuilder) -> Self {
self.project = mutate(self.project);
self
}

pub fn src(mut self, path: impl Into<Utf8PathBuf>, source: impl ToString) -> Self {
self.src.insert(path.into(), source.to_string());
self
}

pub fn lib_rs(self, source: impl ToString) -> Self {
self.src("src/lib.rs", source.to_string())
}

pub fn just_code(&self, t: &impl PathChild) {
for (path, source) in &self.src {
t.child(path).write_str(source).unwrap();
}
}

pub fn build(&self, t: &impl PathChild) {
self.project.just_manifest(t);
self.just_code(t);
}
}

fn cairo_lang_macro_lib_path() -> String {
let path = fsx::canonicalize(
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../plugins/cairo-lang-macro/"),
)
.unwrap();
serde_json::to_string(&path).unwrap()
}

fn simple_project(t: &impl PathChild) {
let macro_lib_path = cairo_lang_macro_lib_path();
CairoPluginProjectBuilder::start()
.scarb_project(|b| {
b.name("hello")
.version("1.0.0")
.manifest_extra(r#"[cairo-plugin]"#)
})
.lib_rs(indoc! {r#"
use cairo_lang_macro::{ProcMacroResult, TokenStream, attribute_macro};
#[attribute_macro]
pub fn some_macro(token_stream: TokenStream) -> ProcMacroResult {
let _code = token_stream.to_string();
ProcMacroResult::Leave
}
"#})
.src(
"Cargo.toml",
formatdoc! {r#"
[package]
name = "proc-macro-stub"
version = "0.1.0"
edition = "2021"
publish = false
[lib]
crate-type = ["rlib","cdylib"]
[dependencies]
cairo-lang-macro = {{ path = {macro_lib_path}}}
"#},
)
.build(t);
}

#[test]
#[ignore = "TODO(maciektr): Remove when proc-macros are implemented."]
fn compile_cairo_plugin() {
let t = TempDir::new().unwrap();
ProjectBuilder::start()
.name("hello")
.version("1.0.0")
.manifest_extra(r#"[cairo-plugin]"#)
.build(&t);

Scarb::quick_snapbox()
.arg("check")
simple_project(&t);
let output = Scarb::quick_snapbox()
.arg("build")
.current_dir(&t)
.assert()
.failure()
.stdout_matches(indoc! {r#"
error: compiling Cairo plugin packages is not possible yet
"#});
.output()
.unwrap();
assert!(
output.status.success(),
"{}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
assert!(stdout.contains("Compiling hello v1.0.0"));
let lines = stdout.lines().map(ToString::to_string).collect::<Vec<_>>();
let (last, lines) = lines.split_last().unwrap();
assert_matches(r#"[..] Finished release target(s) in [..]"#, last);
let (last, _lines) = lines.split_last().unwrap();
// Line from Cargo output
assert_matches(r#"[..]Finished release [optimized] target(s) in[..]"#, last);
}

#[test]
Expand Down

0 comments on commit ce35014

Please sign in to comment.