Skip to content

Commit

Permalink
Use Scarb-managed core in tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mkaput committed Nov 29, 2024
1 parent b087f38 commit 022d3e3
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 11 deletions.
28 changes: 28 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ tempfile = "3"
tracing = "0.1"
tracing-chrome = "0.7.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
which = "7.0.0"

[target.'cfg(target_vendor = "apple")'.dependencies]
libc = "0.2.155"
Expand Down
7 changes: 0 additions & 7 deletions src/project/unmanaged_core_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ pub fn try_to_init_unmanaged_core(
pub fn find_unmanaged_core(config: &Config, scarb: &ScarbToolchain) -> Option<PathBuf> {
find_core_at_config_path(config)
.or_else(|| find_scarb_managed_core(scarb))
.or_else(|| {
if cfg!(feature = "testing") {
cairo_lang_filesystem::detect::detect_corelib()
} else {
None
}
})
.and_then(ensure_absolute)
}

Expand Down
10 changes: 10 additions & 0 deletions src/toolchain/scarb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use anyhow::{Context, Result, bail};
use lsp_types::notification::Notification;
use scarb_metadata::{Metadata, MetadataCommand};
use tracing::{error, warn};
use which::which;

use crate::env_config;
use crate::lsp::ext::ScarbMetadataFailed;
Expand Down Expand Up @@ -47,6 +48,15 @@ impl ScarbToolchain {
fn discover(&self) -> Option<&Path> {
self.scarb_path_cell
.get_or_init(|| {
// While running tests, we do not have SCARB env set,
// but we expect `scarb` binary to be in the PATH.
if cfg!(feature = "testing") {
return Some(
which("scarb")
.expect("running tests requires a `scarb` binary available in `PATH`"),
);
}

let path = env_config::scarb_path();
// TODO(mkaput): Perhaps we should display this notification again after reloading?
if path.is_none() {
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn cairo_projects() {
assert_eq!(normalize(&ls, output), indoc! {r#"
# Analyzed Crates
- `core`: `["[CAIRO_SOURCE]/corelib/src/lib.cairo"]`
- `core`: `["[SCARB_REGISTRY_STD]/core/src/lib.cairo"]`
```rust
CrateSettings {
name: None,
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod fixture;
pub mod jsonrpc;
mod mock_client;
pub mod normalize;
pub mod scarb;

pub use self::cursor::cursors;
pub use self::mock_client::MockClient;
Expand Down
7 changes: 5 additions & 2 deletions tests/e2e/support/normalize.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::path::Path;

use crate::support::fixture::Fixture;
use crate::support::scarb::scarb_registry_std_path;

/// Performs various normalization steps of the input data, to remove any runtime-specific artifacts
/// and make comparisons in test assertions deterministic.
Expand All @@ -19,8 +20,10 @@ fn normalize_well_known_paths(fixture: &Fixture, data: String) -> String {
data = data.replace(&normalize_path(&pwd), "[PWD]");
}

let cairo_source = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap();
data = data.replace(&normalize_path(cairo_source), "[CAIRO_SOURCE]");
let cairols_source = Path::new(env!("CARGO_MANIFEST_DIR"));
data = data.replace(&normalize_path(cairols_source), "[CAIROLS_SOURCE]");

data = data.replace(&normalize_path(scarb_registry_std_path()), "[SCARB_REGISTRY_STD]");

data
}
Expand Down
61 changes: 61 additions & 0 deletions tests/e2e/support/scarb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::LazyLock;

use scarb_metadata::MetadataCommand;
use tempfile::tempdir;

/// Finds Scarb-managed `core` package.
///
/// This is a stripped-down version of similar logic in `unmanaged_core_crate` with these changes:
/// - instant panicking instead of trying to recover,
/// - using `scarb_metadata` directly instead of `ScarbToolchain`,
/// - no tracing.
pub fn scarb_core_path() -> &'static Path {
static CACHE: LazyLock<PathBuf> = LazyLock::new(|| {
let workspace = tempdir().expect("failed to create temporary directory");

let scarb_toml = workspace.path().join("Scarb.toml");
fs::write(
&scarb_toml,
r#"
[package]
name = "cairols_unmanaged_core_lookup"
version = "1.0.0"
"#,
)
.expect("failed to write Scarb.toml");

let metadata = MetadataCommand::new()
.manifest_path(scarb_toml)
.inherit_stderr()
.exec()
.expect("failed to execute: scarb metadata");

// Ensure the workspace directory is deleted after running Scarb.
workspace.close().expect("failed to wipe temporary directory");

// Scarb is expected to generate only one compilation unit (for our stub package)
// that will consist of this package and the `core` crate.
// Therefore, we allow ourselves to liberally just look for any first usage of a package
// named `core` in all compilation units components we got.
metadata
.compilation_units
.into_iter()
.find_map(|compilation_unit| {
compilation_unit
.components
.iter()
.find(|component| component.name == "core")
.map(|component| component.source_root().to_path_buf().into_std_path_buf())
})
.expect("failed to find `core` crate path")
});

&CACHE
}

/// Finds a path where Scarb unpacks its `std` source.
pub fn scarb_registry_std_path() -> &'static Path {
scarb_core_path().parent().unwrap().parent().unwrap()
}
3 changes: 2 additions & 1 deletion tests/e2e/workspace_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use lsp_types::request::Request as _;
use serde_json::json;

use crate::support::sandbox;
use crate::support::scarb::scarb_core_path;

/// The LS used to panic when some files in Salsa database were interned with a relative path.
/// The panic happened while trying to create a `file://` URL to affected file.
Expand All @@ -18,7 +19,7 @@ use crate::support::sandbox;
#[test]
fn relative_path_to_core() {
let core_path = {
let detected = cairo_lang_filesystem::detect::detect_corelib().unwrap();
let detected = scarb_core_path();
let pwd = std::env::current_dir().unwrap();
let path = pathdiff::diff_paths(detected, pwd).unwrap();
assert!(path.is_relative());
Expand Down

0 comments on commit 022d3e3

Please sign in to comment.