Skip to content

Commit

Permalink
Put each binding snapshot test into its own directory
Browse files Browse the repository at this point in the history
  • Loading branch information
ggiraldez committed Jun 26, 2024
1 parent f5cd7bd commit 68a4bfc
Show file tree
Hide file tree
Showing 52 changed files with 164 additions and 141 deletions.
29 changes: 19 additions & 10 deletions crates/codegen/testing/src/bindings_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use anyhow::{bail, Result};
use codegen_language_definition::model::Language;
use inflector::Inflector;
use infra_utils::codegen::CodegenFileSystem;
use infra_utils::paths::FileWalker;
use infra_utils::paths::{FileWalker, PathExtensions};

pub fn generate_bindings_output_tests(
language: &Language,
Expand All @@ -19,11 +19,11 @@ pub fn generate_bindings_output_tests(

generate_mod_file(language, &mut fs, &output_dir.join("mod.rs"), &tests)?;

for (group_name, test_files) in &tests {
for (group_name, test_names) in &tests {
generate_unit_test_file(
&mut fs,
group_name,
test_files,
test_names,
&output_dir.join(format!("{0}.rs", group_name.to_snake_case())),
)?;
}
Expand All @@ -34,22 +34,32 @@ pub fn generate_bindings_output_tests(
fn collect_bindings_tests(data_dir: &Path) -> Result<BTreeMap<String, BTreeSet<String>>> {
let mut tests = BTreeMap::<String, BTreeSet<String>>::new();

for file in FileWalker::from_directory(data_dir).find(["**/*.sol"])? {
for file in FileWalker::from_directory(data_dir).find_all()? {
if let Ok(generated_dir) = file.generated_dir() {
assert!(
generated_dir.unwrap_parent().join("input.sol").exists(),
"Each snapshot should have a matching input.sol test file: {file:?}",
);

// skip generated files
continue;
}

let parts: Vec<_> = file
.strip_prefix(data_dir)?
.iter()
.map(|p| p.to_str().unwrap())
.collect();

match parts[..] {
[group_name, test_file] => {
[group_name, test_name, "input.sol"] => {
tests
.entry(group_name.to_owned())
.or_default()
.insert(test_file.to_owned());
.insert(test_name.to_owned());
}
_ => {
bail!("Invalid test input. Should be in the form of '<tests-dir>/GROUP_NAME/TEST_FILE.sol', but found: {file:?}");
bail!("Invalid test input. Should be in the form of '<tests-dir>/GROUP_NAME/TEST_NAME/input.sol', but found: {file:?}");
}
};
}
Expand Down Expand Up @@ -107,14 +117,13 @@ fn generate_unit_test_file(
) -> Result<()> {
let unit_tests_str = test_files
.iter()
.fold(String::new(), |mut buffer, test_file| {
let test_name = test_file.strip_suffix(".sol").unwrap().to_snake_case();
.fold(String::new(), |mut buffer, test_name| {
writeln!(
buffer,
r#"
#[test]
fn {test_name}() -> Result<()> {{
run("{group_name}", "{test_file}")
run("{group_name}", "{test_name}")
}}
"#
)
Expand Down
5 changes: 3 additions & 2 deletions crates/infra/utils/src/codegen/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ fn generate_header(file_path: &Path) -> String {
"json" => String::new(),
"html" | "md" => format!("<!-- {warning_line} -->"),
"js" | "rs" | "ts" => format!("// {warning_line}"),
"yml" => format!("# {warning_line}"),
"yml" | "txt" => format!("# {warning_line}"),
"mmd" => format!("%% {warning_line}"),
ext => panic!("Unsupported extension to generate a header for: {ext}"),
};
}
Expand All @@ -48,7 +49,7 @@ fn run_formatter(file_path: &Path, contents: &str) -> Result<String> {
return match get_extension(file_path) {
"js" | "json" | "ts" => run_prettier(file_path, contents),
"rs" => run_rustfmt(contents),
"html" | "md" | "yml" => {
"html" | "md" | "mmd" | "txt" | "yml" => {
// We already generate formatted content for these, so no need to run expensive formatting.
Ok(contents.to_owned())
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

79 changes: 40 additions & 39 deletions crates/solidity/outputs/cargo/tests/src/bindings_output/runner.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::fmt;
use std::fs::{self, create_dir_all};
use std::io::BufWriter;
use std::ops::Range;
use std::path::Path;

use anyhow::Result;
use ariadne::{Color, Config, Label, Report, ReportBuilder, ReportKind, Source};
use infra_utils::cargo::CargoWorkspace;
use infra_utils::codegen::CodegenFileSystem;
use infra_utils::paths::PathExtensions;
use metaslang_graph_builder::stack_graph;
use semver::Version;
use slang_solidity::bindings::graph_builder::{
Expand All @@ -18,40 +19,44 @@ use slang_solidity::parse_output::ParseOutput;

use super::generated::VERSION_BREAKS;

pub fn run(group_name: &str, file_name: &str) -> Result<()> {
let data_dir = CargoWorkspace::locate_source_crate("solidity_testing_snapshots")?
pub fn run(group_name: &str, test_name: &str) -> Result<()> {
let test_dir = CargoWorkspace::locate_source_crate("solidity_testing_snapshots")?
.join("bindings_output")
.join(group_name);
let input_path = data_dir.join(file_name);
let input = fs::read_to_string(&input_path)?;
.join(group_name)
.join(test_name);

let output_dir = data_dir.join("generated");
create_dir_all(&output_dir)?;
let mut fs = CodegenFileSystem::new(&test_dir)?;

let input_path = test_dir.join("input.sol");

let source = input_path.read_to_string()?;

let mut last_graph_output = None;
let mut last_bindings_output = None;

for version in &VERSION_BREAKS {
let language = Language::new(version.clone())?;

let parse_output = language.parse(Language::ROOT_KIND, &input);
let parse_output = language.parse(Language::ROOT_KIND, &source);

let graph_output = output_graph(version, file_name, &parse_output)?;
let graph_output = output_graph(version, &parse_output)?;
match last_graph_output {
Some(ref last) if last == &graph_output => (),
_ => {
let graph_output_path = output_dir.join(format!("{file_name}-{version}.mmd"));
fs::write(graph_output_path, &graph_output)?;
let snapshot_path = test_dir.join("generated").join(format!("{version}.mmd"));

fs.write_file(snapshot_path, &graph_output)?;
last_graph_output = Some(graph_output);
}
};

let bindings_output = output_bindings(version, &parse_output, &input, &input_path)?;
let bindings_output = output_bindings(version, &parse_output, &source, &input_path)?;
match last_bindings_output {
Some(ref last) if last == &bindings_output => (),
_ => {
let bindings_output_path = output_dir.join(format!("{file_name}-{version}.txt"));
fs::write(bindings_output_path, &bindings_output)?;
let snapshot_path = test_dir.join("generated").join(format!("{version}.txt"));

fs.write_file(snapshot_path, &bindings_output)?;
last_bindings_output = Some(bindings_output);
}
}
Expand All @@ -67,7 +72,7 @@ const VARIABLE_DEBUG_ATTR: &str = "__variable";
const LOCATION_DEBUG_ATTR: &str = "__location";
const MATCH_DEBUG_ATTR: &str = "__match";

fn output_graph(version: &Version, file_name: &str, parse_output: &ParseOutput) -> Result<String> {
fn output_graph(version: &Version, parse_output: &ParseOutput) -> Result<String> {
let graph_builder = Bindings::get_graph_builder()?;

let tree = parse_output.create_tree_cursor();
Expand All @@ -90,18 +95,14 @@ fn output_graph(version: &Version, file_name: &str, parse_output: &ParseOutput)

graph_builder.execute_into(&mut graph, &tree, &execution_config, &NoCancellation)?;

let title = format!(
"{file_name}{note}",
note = if !parse_output.is_valid() {
" - Parsing failed, graph may be incomplete"
} else {
""
}
);
let note = if parse_output.is_valid() {
""
} else {
"%% WARNING: Parsing failed, graph may be incomplete\n"
};
Ok(format!(
"---\ntitle: {}\n---\n{}",
title,
print_graph_as_mermaid(&graph)
"{note}{graph}",
graph = print_graph_as_mermaid(&graph)
))
}

Expand Down Expand Up @@ -154,19 +155,19 @@ fn print_graph_as_mermaid(graph: &Graph) -> impl fmt::Display + '_ {
fn output_bindings(
version: &Version,
parse_output: &ParseOutput,
input: &str,
input_path: &Path,
source: &str,
source_path: &Path,
) -> Result<String> {
let mut bindings = Bindings::create(version.clone());
bindings.add_file(
input_path.to_str().unwrap(),
source_path.to_str().unwrap(),
parse_output.create_tree_cursor(),
)?;

let file_id = input_path.file_name().unwrap().to_str().unwrap();
let source_id = source_path.strip_repo_root()?.unwrap_str();
let mut builder: ReportBuilder<'_, (&str, Range<usize>)> = Report::build(
ReportKind::Custom("References and definitions", Color::Unset),
file_id,
source_id,
0,
)
.with_config(Config::default().with_color(false));
Expand All @@ -184,14 +185,14 @@ fn output_bindings(

let range = {
let range = cursor.text_range();
let start = input[..range.start.utf8].chars().count();
let end = input[..range.end.utf8].chars().count();
let start = source[..range.start.utf8].chars().count();
let end = source[..range.end.utf8].chars().count();
start..end
};

definitions.push(definition);
let message = format!("def: {}", definitions.len());
builder = builder.with_label(Label::new((file_id, range)).with_message(message));
builder = builder.with_label(Label::new((source_id, range)).with_message(message));
}

for reference in bindings.all_references() {
Expand All @@ -201,8 +202,8 @@ fn output_bindings(

let range = {
let range = cursor.text_range();
let start = input[..range.start.utf8].chars().count();
let end = input[..range.end.utf8].chars().count();
let start = source[..range.start.utf8].chars().count();
let end = source[..range.end.utf8].chars().count();
start..end
};

Expand All @@ -215,12 +216,12 @@ fn output_bindings(
}
};

builder = builder.with_label(Label::new((file_id, range)).with_message(message));
builder = builder.with_label(Label::new((source_id, range)).with_message(message));
}

let report = builder.finish();
let mut buffer = BufWriter::new(Vec::new());
report.write((file_id, Source::from(input)), &mut buffer)?;
report.write((source_id, Source::from(source)), &mut buffer)?;

let result = String::from_utf8(buffer.buffer().to_vec())?;
Ok(result)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: decls.sol - Parsing failed, graph may be incomplete
---
%% This file is generated automatically by infrastructure scripts. Please don't edit by hand.

%% WARNING: Parsing failed, graph may be incomplete
graph TD
N0["`**0** @(1, 1)
ROOT_NODE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# This file is generated automatically by infrastructure scripts. Please don't edit by hand.

References and definitions:
╭─[decls.sol:1:1]
╭─[crates/solidity/testing/snapshots/bindings_output/enums/decls/input.sol:1:1]
1 │ contract Test {
│ ──┬─
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
title: decls.sol
---
%% This file is generated automatically by infrastructure scripts. Please don't edit by hand.

graph TD
N0["`**0** @(1, 1)
ROOT_NODE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# This file is generated automatically by infrastructure scripts. Please don't edit by hand.

References and definitions:
╭─[decls.sol:1:1]
╭─[crates/solidity/testing/snapshots/bindings_output/enums/decls/input.sol:1:1]
1 │ contract Test {
│ ──┬─
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
title: in_params.sol
---
%% This file is generated automatically by infrastructure scripts. Please don't edit by hand.

graph TD
N0["`**0** @(1, 1)
ROOT_NODE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# This file is generated automatically by infrastructure scripts. Please don't edit by hand.

References and definitions:
╭─[in_params.sol:1:1]
╭─[crates/solidity/testing/snapshots/bindings_output/enums/in_params/input.sol:1:1]
1 │ contract Test {
│ ──┬─
Expand Down
Loading

0 comments on commit 68a4bfc

Please sign in to comment.