2022-11-30 01:17:34 +01:00
|
|
|
use std::env;
|
|
|
|
use std::fs;
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::process::Command;
|
|
|
|
|
2022-12-01 01:33:38 +01:00
|
|
|
use php_parser_rs::prelude::Lexer;
|
|
|
|
use php_parser_rs::prelude::Parser;
|
2022-11-30 01:17:34 +01:00
|
|
|
|
|
|
|
#[test]
|
2022-12-05 07:17:19 +01:00
|
|
|
fn third_party_1_php_standard_library() {
|
2022-11-30 01:17:34 +01:00
|
|
|
test_repository(
|
|
|
|
"php-standard-library",
|
|
|
|
"https://github.com/azjezz/psl.git",
|
|
|
|
"2.2.x",
|
|
|
|
&["src", "tests", "examples"],
|
2022-12-05 13:37:05 +01:00
|
|
|
&[],
|
2022-11-30 01:17:34 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-12-05 01:18:20 +01:00
|
|
|
#[test]
|
2022-12-05 07:17:19 +01:00
|
|
|
fn third_party_2_laravel_framework() {
|
2022-12-05 01:18:20 +01:00
|
|
|
test_repository(
|
|
|
|
"laravel-framework",
|
|
|
|
"https://github.com/laravel/framework",
|
|
|
|
"9.x",
|
|
|
|
&["src", "tests"],
|
2022-12-05 13:37:05 +01:00
|
|
|
&[],
|
2022-12-05 01:18:20 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-12-05 07:17:19 +01:00
|
|
|
#[test]
|
|
|
|
fn third_party_3_symfony_framework() {
|
|
|
|
test_repository(
|
|
|
|
"symfony-framework",
|
|
|
|
"https://github.com/symfony/symfony",
|
|
|
|
"6.3",
|
|
|
|
&["src/Symfony"],
|
2022-12-05 14:39:59 +01:00
|
|
|
&[
|
|
|
|
"src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php",
|
2022-12-05 14:46:48 +01:00
|
|
|
"src/Symfony/Component/Config/Tests/Fixtures/ParseError.php",
|
2022-12-05 14:39:59 +01:00
|
|
|
// FIXME: Remove this one once I've found the energy to sort out heredocs / nowdocs.
|
2022-12-05 14:46:48 +01:00
|
|
|
"src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/LazyServiceDumper.php",
|
2022-12-05 14:55:35 +01:00
|
|
|
"src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php",
|
2022-12-05 15:48:46 +01:00
|
|
|
// FIXME: Remove this once we can support (A&B)|C DNF types.
|
|
|
|
"src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/compositetype_classes.php",
|
|
|
|
// FIXME: Remove these once we can support arbitrary opening and closing tags.
|
|
|
|
"src/Symfony/Component/ErrorHandler/Resources/views/exception.html.php",
|
|
|
|
"src/Symfony/Component/ErrorHandler/Resources/views/exception_full.html.php",
|
|
|
|
"src/Symfony/Component/ErrorHandler/Resources/views/logs.html.php",
|
|
|
|
"src/Symfony/Component/ErrorHandler/Resources/views/trace.html.php",
|
|
|
|
"src/Symfony/Component/ErrorHandler/Resources/views/traces.html.php",
|
|
|
|
"src/Symfony/Component/ErrorHandler/Resources/views/traces_text.html.php"
|
2022-12-05 14:39:59 +01:00
|
|
|
],
|
2022-12-05 07:17:19 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-12-05 13:37:05 +01:00
|
|
|
fn test_repository(
|
|
|
|
name: &str,
|
|
|
|
repository: &str,
|
|
|
|
branch: &str,
|
|
|
|
directories: &[&str],
|
|
|
|
ignore: &[&str],
|
|
|
|
) {
|
2022-11-30 01:17:34 +01:00
|
|
|
let out_dir = env::var_os("OUT_DIR").expect("failed to get OUT_DIR");
|
|
|
|
let out_path = PathBuf::from(out_dir).join(name);
|
|
|
|
|
|
|
|
if !out_path.exists() {
|
|
|
|
let output = Command::new("git")
|
|
|
|
.arg("clone")
|
|
|
|
.arg("--depth")
|
|
|
|
.arg("1")
|
|
|
|
.arg("-b")
|
|
|
|
.arg(branch)
|
|
|
|
.arg(repository)
|
|
|
|
.arg(&out_path)
|
|
|
|
.output()
|
|
|
|
.expect("failed to run git.");
|
|
|
|
|
|
|
|
if !output.status.success() {
|
|
|
|
panic!("failed to clone repository: {:#?}", output)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for dir in directories {
|
2022-12-05 12:58:52 +01:00
|
|
|
test_directory(out_path.clone(), out_path.join(dir), ignore);
|
2022-11-30 01:17:34 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-05 12:58:52 +01:00
|
|
|
fn test_directory(root: PathBuf, directory: PathBuf, ignore: &[&str]) {
|
|
|
|
let mut entries = fs::read_dir(&directory)
|
2022-11-30 01:17:34 +01:00
|
|
|
.unwrap()
|
|
|
|
.flatten()
|
|
|
|
.map(|entry| entry.path())
|
|
|
|
.collect::<Vec<PathBuf>>();
|
|
|
|
|
|
|
|
entries.sort();
|
|
|
|
|
|
|
|
for entry in entries {
|
|
|
|
if entry.is_dir() {
|
2022-12-05 12:58:52 +01:00
|
|
|
test_directory(root.clone(), entry, ignore);
|
2022-11-30 01:17:34 +01:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-12-05 13:37:05 +01:00
|
|
|
if entry.is_file()
|
|
|
|
&& entry.extension().unwrap_or_default() == "php"
|
|
|
|
&& !ignore.contains(
|
|
|
|
&entry
|
|
|
|
.as_path()
|
|
|
|
.strip_prefix(&root)
|
|
|
|
.unwrap()
|
|
|
|
.to_str()
|
|
|
|
.unwrap(),
|
|
|
|
)
|
|
|
|
{
|
2022-11-30 01:17:34 +01:00
|
|
|
let name_entry = entry.clone();
|
|
|
|
let fullanme_string = name_entry.to_string_lossy();
|
|
|
|
let name = fullanme_string
|
|
|
|
.strip_prefix(root.to_str().unwrap())
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
test_file(name, entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_file(name: &str, filename: PathBuf) {
|
2022-12-05 14:39:59 +01:00
|
|
|
let code = std::fs::read(&filename).unwrap();
|
2022-11-30 01:17:34 +01:00
|
|
|
|
2022-12-01 01:33:38 +01:00
|
|
|
Lexer::new()
|
2022-12-05 14:39:59 +01:00
|
|
|
.tokenize(&code)
|
2022-11-30 01:17:34 +01:00
|
|
|
.map(|tokens| {
|
2022-12-01 03:49:51 +01:00
|
|
|
Parser::new()
|
2022-11-30 01:17:34 +01:00
|
|
|
.parse(tokens)
|
|
|
|
.map(|_| {
|
|
|
|
println!("✅ successfully parsed file: `\"{}\"`.", name);
|
|
|
|
})
|
|
|
|
.unwrap_or_else(|error| {
|
|
|
|
panic!("❌ failed to parse file: `\"{name}\"`, error: {error:?}")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.unwrap_or_else(|error| {
|
|
|
|
panic!("❌ failed to tokenize file: `\"{name}\"`, error: {error:?}")
|
|
|
|
});
|
|
|
|
}
|