test: add unique flatten test (#995)
This commit is contained in:
parent
1641be7395
commit
fab30887a2
|
@ -10,6 +10,7 @@ use crate::{
|
||||||
use crate::artifacts::output_selection::ContractOutputSelection;
|
use crate::artifacts::output_selection::ContractOutputSelection;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::HashSet,
|
||||||
fmt::{self, Formatter},
|
fmt::{self, Formatter},
|
||||||
fs,
|
fs,
|
||||||
path::{Component, Path, PathBuf},
|
path::{Component, Path, PathBuf},
|
||||||
|
@ -229,7 +230,7 @@ impl ProjectPathsConfig {
|
||||||
pub fn flatten(&self, target: &Path) -> Result<String> {
|
pub fn flatten(&self, target: &Path) -> Result<String> {
|
||||||
tracing::trace!("flattening file");
|
tracing::trace!("flattening file");
|
||||||
let graph = Graph::resolve(self)?;
|
let graph = Graph::resolve(self)?;
|
||||||
self.flatten_node(target, &graph, &mut vec![], false, false)
|
self.flatten_node(target, &graph, &mut Default::default(), false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flattens a single node from the dependency graph
|
/// Flattens a single node from the dependency graph
|
||||||
|
@ -237,7 +238,7 @@ impl ProjectPathsConfig {
|
||||||
&self,
|
&self,
|
||||||
target: &Path,
|
target: &Path,
|
||||||
graph: &Graph,
|
graph: &Graph,
|
||||||
imported: &mut Vec<usize>,
|
imported: &mut HashSet<usize>,
|
||||||
strip_version_pragma: bool,
|
strip_version_pragma: bool,
|
||||||
strip_license: bool,
|
strip_license: bool,
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
|
@ -248,9 +249,11 @@ impl ProjectPathsConfig {
|
||||||
SolcError::msg(format!("cannot resolve file at \"{:?}\"", target.display()))
|
SolcError::msg(format!("cannot resolve file at \"{:?}\"", target.display()))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if imported.iter().any(|&idx| idx == *target_index) {
|
if imported.contains(target_index) {
|
||||||
|
// short circuit nodes that were already imported, if both A.sol and B.sol import C.sol
|
||||||
return Ok(String::new())
|
return Ok(String::new())
|
||||||
}
|
}
|
||||||
|
imported.insert(*target_index);
|
||||||
|
|
||||||
let target_node = graph.node(*target_index);
|
let target_node = graph.node(*target_index);
|
||||||
|
|
||||||
|
@ -278,21 +281,17 @@ impl ProjectPathsConfig {
|
||||||
|
|
||||||
for import in imports.iter() {
|
for import in imports.iter() {
|
||||||
let import_path = self.resolve_import(target_dir, import.data())?;
|
let import_path = self.resolve_import(target_dir, import.data())?;
|
||||||
let import_content = self
|
let s = self.flatten_node(&import_path, graph, imported, true, true)?;
|
||||||
.flatten_node(&import_path, graph, imported, true, true)?
|
let import_content = s.trim().as_bytes();
|
||||||
.trim()
|
|
||||||
.as_bytes()
|
|
||||||
.to_owned();
|
|
||||||
let import_content_len = import_content.len() as isize;
|
let import_content_len = import_content.len() as isize;
|
||||||
let (start, end) = import.loc_by_offset(offset);
|
let (start, end) = import.loc_by_offset(offset);
|
||||||
content.splice(start..end, import_content);
|
content.splice(start..end, import_content.iter().copied());
|
||||||
offset += import_content_len - ((end - start) as isize);
|
offset += import_content_len - ((end - start) as isize);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = String::from_utf8(content).map_err(|err| {
|
let result = String::from_utf8(content).map_err(|err| {
|
||||||
SolcError::msg(format!("failed to convert extended bytes to string: {}", err))
|
SolcError::msg(format!("failed to convert extended bytes to string: {}", err))
|
||||||
})?;
|
})?;
|
||||||
imported.push(*target_index);
|
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,6 +417,57 @@ fn can_flatten_file_in_dapp_sample() {
|
||||||
assert!(result.contains("contract DappTest"));
|
assert!(result.contains("contract DappTest"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_flatten_unique() {
|
||||||
|
let project = TempProject::dapptools().unwrap();
|
||||||
|
|
||||||
|
let f = project
|
||||||
|
.add_source(
|
||||||
|
"A",
|
||||||
|
r#"
|
||||||
|
pragma solidity ^0.8.10;
|
||||||
|
import "./C.sol";
|
||||||
|
import "./B.sol";
|
||||||
|
contract A { }
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
project
|
||||||
|
.add_source(
|
||||||
|
"B",
|
||||||
|
r#"
|
||||||
|
pragma solidity ^0.8.10;
|
||||||
|
import "./C.sol";
|
||||||
|
contract B { }
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
project
|
||||||
|
.add_source(
|
||||||
|
"C",
|
||||||
|
r#"
|
||||||
|
pragma solidity ^0.8.10;
|
||||||
|
import "./A.sol";
|
||||||
|
contract C { }
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let result = project.flatten(&f).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
result,
|
||||||
|
r#"
|
||||||
|
pragma solidity ^0.8.10;
|
||||||
|
contract C { }
|
||||||
|
contract B { }
|
||||||
|
contract A { }
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_flatten_file_with_duplicates() {
|
fn can_flatten_file_with_duplicates() {
|
||||||
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test-data/test-flatten-duplicates");
|
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test-data/test-flatten-duplicates");
|
||||||
|
|
Loading…
Reference in New Issue