mirror of https://github.com/astral-sh/ruff
[red-knot] Once again, add more tests asserting that the `VendoredFileSystem` and the `VERSIONS` parser work with the vendored typeshed stubs (#11987)
This commit is contained in:
parent
92b145e56a
commit
f846fc9e07
|
|
@ -29,6 +29,7 @@ zip = { workspace = true }
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
insta = { workspace = true }
|
insta = { workspace = true }
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
|
walkdir = { workspace = true }
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,20 @@ pub(crate) mod versions;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use ruff_db::vendored::VendoredFileSystem;
|
||||||
|
use ruff_db::vfs::VendoredPath;
|
||||||
|
|
||||||
|
// The file path here is hardcoded in this crate's `build.rs` script.
|
||||||
|
// Luckily this crate will fail to build if this file isn't available at build time.
|
||||||
|
const TYPESHED_ZIP_BYTES: &[u8] =
|
||||||
|
include_bytes!(concat!(env!("OUT_DIR"), "/zipped_typeshed.zip"));
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn typeshed_zip_created_at_build_time() -> anyhow::Result<()> {
|
fn typeshed_zip_created_at_build_time() {
|
||||||
// The file path here is hardcoded in this crate's `build.rs` script.
|
let mut typeshed_zip_archive =
|
||||||
// Luckily this crate will fail to build if this file isn't available at build time.
|
zip::ZipArchive::new(io::Cursor::new(TYPESHED_ZIP_BYTES)).unwrap();
|
||||||
const TYPESHED_ZIP_BYTES: &[u8] =
|
|
||||||
include_bytes!(concat!(env!("OUT_DIR"), "/zipped_typeshed.zip"));
|
|
||||||
|
|
||||||
let mut typeshed_zip_archive = zip::ZipArchive::new(io::Cursor::new(TYPESHED_ZIP_BYTES))?;
|
|
||||||
|
|
||||||
let mut functools_module_stub = typeshed_zip_archive
|
let mut functools_module_stub = typeshed_zip_archive
|
||||||
.by_name("stdlib/functools.pyi")
|
.by_name("stdlib/functools.pyi")
|
||||||
|
|
@ -19,9 +24,72 @@ mod tests {
|
||||||
assert!(functools_module_stub.is_file());
|
assert!(functools_module_stub.is_file());
|
||||||
|
|
||||||
let mut functools_module_stub_source = String::new();
|
let mut functools_module_stub_source = String::new();
|
||||||
functools_module_stub.read_to_string(&mut functools_module_stub_source)?;
|
functools_module_stub
|
||||||
|
.read_to_string(&mut functools_module_stub_source)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert!(functools_module_stub_source.contains("def update_wrapper("));
|
assert!(functools_module_stub_source.contains("def update_wrapper("));
|
||||||
Ok(())
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn typeshed_vfs_consistent_with_vendored_stubs() {
|
||||||
|
let vendored_typeshed_dir = Path::new("vendor/typeshed").canonicalize().unwrap();
|
||||||
|
let vendored_typeshed_stubs = VendoredFileSystem::new(TYPESHED_ZIP_BYTES).unwrap();
|
||||||
|
|
||||||
|
let mut empty_iterator = true;
|
||||||
|
for entry in walkdir::WalkDir::new(&vendored_typeshed_dir).min_depth(1) {
|
||||||
|
empty_iterator = false;
|
||||||
|
let entry = entry.unwrap();
|
||||||
|
let absolute_path = entry.path();
|
||||||
|
let file_type = entry.file_type();
|
||||||
|
|
||||||
|
let relative_path = absolute_path
|
||||||
|
.strip_prefix(&vendored_typeshed_dir)
|
||||||
|
.unwrap_or_else(|_| {
|
||||||
|
panic!("Expected {absolute_path:?} to be a child of {vendored_typeshed_dir:?}")
|
||||||
|
});
|
||||||
|
|
||||||
|
let posix_style_path = relative_path
|
||||||
|
.as_os_str()
|
||||||
|
.to_str()
|
||||||
|
.unwrap_or_else(|| panic!("Expected {relative_path:?} to be a valid UTF-8 path"));
|
||||||
|
|
||||||
|
let vendored_path = VendoredPath::new(posix_style_path);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
vendored_typeshed_stubs.exists(vendored_path),
|
||||||
|
"Expected {vendored_path:?} to exist in the `VendoredFileSystem`!
|
||||||
|
|
||||||
|
Vendored file system:
|
||||||
|
|
||||||
|
{vendored_typeshed_stubs:#?}
|
||||||
|
"
|
||||||
|
);
|
||||||
|
|
||||||
|
let vendored_path_kind = vendored_typeshed_stubs
|
||||||
|
.metadata(vendored_path)
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"Expected metadata for {vendored_path:?} to be retrievable from the `VendoredFileSystem!
|
||||||
|
|
||||||
|
Vendored file system:
|
||||||
|
|
||||||
|
{vendored_typeshed_stubs:#?}
|
||||||
|
"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.kind();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
vendored_path_kind.is_directory(),
|
||||||
|
file_type.is_dir(),
|
||||||
|
"{vendored_path:?} had type {vendored_path_kind:?}, inconsistent with fs path {relative_path:?}: {file_type:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
!empty_iterator,
|
||||||
|
"Expected there to be at least one file or directory in the vendored typeshed stubs!"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -308,11 +308,14 @@ impl From<SupportedPyVersion> for PyVersion {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::num::{IntErrorKind, NonZeroU16};
|
use std::num::{IntErrorKind, NonZeroU16};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use insta::assert_snapshot;
|
use insta::assert_snapshot;
|
||||||
|
|
||||||
|
const TYPESHED_STDLIB_DIR: &str = "stdlib";
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
const ONE: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(1) };
|
const ONE: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(1) };
|
||||||
|
|
||||||
|
|
@ -345,6 +348,60 @@ mod tests {
|
||||||
assert!(!versions.module_exists_on_version(audioop, SupportedPyVersion::Py313));
|
assert!(!versions.module_exists_on_version(audioop, SupportedPyVersion::Py313));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn typeshed_versions_consistent_with_vendored_stubs() {
|
||||||
|
const VERSIONS_DATA: &str = include_str!("../../vendor/typeshed/stdlib/VERSIONS");
|
||||||
|
let vendored_typeshed_dir = Path::new("vendor/typeshed").canonicalize().unwrap();
|
||||||
|
let vendored_typeshed_versions = TypeshedVersions::from_str(VERSIONS_DATA).unwrap();
|
||||||
|
|
||||||
|
let mut empty_iterator = true;
|
||||||
|
|
||||||
|
let stdlib_stubs_path = vendored_typeshed_dir.join(TYPESHED_STDLIB_DIR);
|
||||||
|
|
||||||
|
for entry in std::fs::read_dir(&stdlib_stubs_path).unwrap() {
|
||||||
|
empty_iterator = false;
|
||||||
|
let entry = entry.unwrap();
|
||||||
|
let absolute_path = entry.path();
|
||||||
|
|
||||||
|
let relative_path = absolute_path
|
||||||
|
.strip_prefix(&stdlib_stubs_path)
|
||||||
|
.unwrap_or_else(|_| panic!("Expected path to be a child of {stdlib_stubs_path:?} but found {absolute_path:?}"));
|
||||||
|
|
||||||
|
let relative_path_str = relative_path.as_os_str().to_str().unwrap_or_else(|| {
|
||||||
|
panic!("Expected all typeshed paths to be valid UTF-8; got {relative_path:?}")
|
||||||
|
});
|
||||||
|
if relative_path_str == "VERSIONS" {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let top_level_module = if let Some(extension) = relative_path.extension() {
|
||||||
|
// It was a file; strip off the file extension to get the module name:
|
||||||
|
let extension = extension
|
||||||
|
.to_str()
|
||||||
|
.unwrap_or_else(||panic!("Expected all file extensions to be UTF-8; was not true for {relative_path:?}"));
|
||||||
|
|
||||||
|
relative_path_str
|
||||||
|
.strip_suffix(extension)
|
||||||
|
.and_then(|string| string.strip_suffix('.')).unwrap_or_else(|| {
|
||||||
|
panic!("Expected path {relative_path_str:?} to end with computed extension {extension:?}")
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// It was a directory; no need to do anything to get the module name
|
||||||
|
relative_path_str
|
||||||
|
};
|
||||||
|
|
||||||
|
let top_level_module = ModuleName::new(top_level_module)
|
||||||
|
.unwrap_or_else(|| panic!("{top_level_module:?} was not a valid module name!"));
|
||||||
|
|
||||||
|
assert!(vendored_typeshed_versions.contains_module(&top_level_module));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
!empty_iterator,
|
||||||
|
"Expected there to be at least one file or directory in the vendored typeshed stubs"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_parse_mock_versions_file() {
|
fn can_parse_mock_versions_file() {
|
||||||
const VERSIONS: &str = "\
|
const VERSIONS: &str = "\
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue