Skip to content

Commit bf8b9a0

Browse files
committed
IdMap unit'y test with assignments (and add but-testsupport::Sandbox)
This also makes the Sandbox more generally available, in support of a more generalised testing style of somewhat higher-level functions that use the context.
1 parent 4a29a19 commit bf8b9a0

File tree

34 files changed

+691
-522
lines changed

34 files changed

+691
-522
lines changed

.github/workflows/push.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ jobs:
135135
- run: cargo check --workspace --all-targets
136136
- run: |
137137
# should work without the "legacy" feature
138+
cargo check -p but-testsupport --all-targets
139+
cargo check -p but-testsupport --all-targets --features sandbox
140+
cargo check -p but-testsupport --all-targets --features sandbox-but-api
138141
cargo check -p but-ctx --all-targets
139142
cargo check -p but-serde --all-targets
140143
cargo check -p but-meta --all-targets

Cargo.lock

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ regex = { version = "1.11.3", default-features = false, features = ["std", "unic
124124
clap = { version = "4.5.53", default-features = false, features = ["derive", "std", "help", "unstable-markdown"]}
125125
tracing-forest = { version = "0.3.0" }
126126
sysinfo = { version = "0.37.2", default-features = false }
127+
shell-words = "1.1.0"
127128

128129
[profile.release]
129130
# There are no overrides here as we optimise for fast release builds,

crates/but-meta/src/legacy.rs

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -217,17 +217,44 @@ impl Snapshot {
217217

218218
let ws = graph.to_workspace()?;
219219
let mut seen = BTreeSet::new();
220-
for (ws_stack, in_workspace_stack_id) in
221-
ws.stacks.iter().filter_map(|s| s.id.map(|id| (s, id)))
222-
{
223-
seen.insert(in_workspace_stack_id);
224-
let Some(vb_stack) = self.content.branches.get_mut(&in_workspace_stack_id) else {
225-
tracing::warn!(
226-
"Didn't find stack with id {in_workspace_stack_id} in branches metadata, and it would have to be created or old code may fail"
227-
);
228-
continue;
229-
};
230220

221+
// Make sure we have a stack id, which is something that may not be the case in
222+
// single-branch mode or in tests that start off with just a Git repository.
223+
// Having stack IDs is useful and maybe one day we can pre-generate them just like we do here
224+
// as they only have to be locally unique.
225+
let workspace_unique_stack_id = |mut idx: usize| -> StackId {
226+
let mut stack_id = StackId::from_number_for_testing(idx as u128);
227+
while self.content.branches.contains_key(&stack_id) {
228+
idx += 1;
229+
stack_id = StackId::from_number_for_testing(idx as u128);
230+
}
231+
stack_id
232+
};
233+
let ws_stacks_to_represent_in_vb_toml: Vec<_> = ws
234+
.stacks
235+
.iter()
236+
.enumerate()
237+
.map(|(idx, s)| {
238+
let id = s.id.unwrap_or_else(|| workspace_unique_stack_id(idx + 1));
239+
(s, id, idx)
240+
})
241+
.collect();
242+
for (ws_stack, in_workspace_stack_id, ws_stack_idx) in ws_stacks_to_represent_in_vb_toml {
243+
seen.insert(in_workspace_stack_id);
244+
let mut inserted_new_stack = false;
245+
let vb_stack = self
246+
.content
247+
.branches
248+
.entry(in_workspace_stack_id)
249+
.or_insert_with(|| {
250+
inserted_new_stack = true;
251+
Stack::new_with_just_heads(
252+
vec![],
253+
gix::date::Time::now_utc().seconds as u128 * 1000,
254+
ws_stack_idx,
255+
true,
256+
)
257+
});
231258
let made_heads_match = make_heads_match(ws_stack, vb_stack);
232259
if !vb_stack.in_workspace {
233260
tracing::warn!(
@@ -242,16 +269,19 @@ impl Snapshot {
242269
);
243270
self.set_changed_to_necessitate_write();
244271
}
272+
if inserted_new_stack {
273+
self.set_changed_to_necessitate_write();
274+
}
245275
}
246276

247-
let stack_ids_to_put_in_workspace: Vec<_> = sideeffect_free_meta
277+
let stack_ids_to_remove_from_workspace: Vec<_> = sideeffect_free_meta
248278
.data()
249279
.branches
250280
.keys()
251281
.filter(|stack_id| !seen.contains(stack_id))
252282
.copied()
253283
.collect();
254-
for stack_id_not_in_workspace in stack_ids_to_put_in_workspace {
284+
for stack_id_not_in_workspace in stack_ids_to_remove_from_workspace {
255285
let vb_stack = self
256286
.content
257287
.branches

crates/but-testing/src/command/project.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub fn add(data_dir: PathBuf, path: PathBuf, refname: Option<RemoteRefname>) ->
1313
.context("Only non-bare repositories can be added")?
1414
.to_owned()
1515
.canonicalize()?;
16-
let outcome = gitbutler_project::add_with_path(data_dir, path)?;
16+
let outcome = gitbutler_project::add_at_app_data_dir(data_dir, path)?;
1717
let project = outcome.try_project()?;
1818

1919
let ctx = Context::new_from_legacy_project_and_settings(&project, AppSettings::default());

crates/but-testsupport/Cargo.toml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,37 @@ publish = false
77
rust-version = "1.89"
88

99
[lib]
10+
test = false
1011
doctest = false
1112

1213
[features]
1314
snapbox = ["dep:snapbox"]
15+
sandbox = [
16+
"snapbox",
17+
"dep:shell-words",
18+
"dep:but-meta",
19+
]
20+
## Activate API testing support, so the sandbox is made so it can also isolate a GitButler application for use with the `but-api`.
21+
sandbox-but-api = [
22+
"sandbox",
23+
"dep:but-ctx",
24+
"dep:but-settings",
25+
]
1426

1527
[dependencies]
1628
but-graph.workspace = true
1729
but-core.workspace = true
30+
but-settings = { workspace = true, optional = true }
31+
but-meta = { workspace = true, optional = true, features = ["legacy"] }
32+
but-ctx = { workspace = true, optional = true }
1833

19-
gix-testtools.workspace = true
34+
shell-words = { workspace = true, optional = true }
2035

36+
gix-testtools.workspace = true
2137
gix.workspace = true
2238
anyhow.workspace = true
2339
termtree = "0.5.1"
2440
regex = { workspace = true }
25-
snapbox = { workspace = true, optional = true }
41+
snapbox = { workspace = true, optional = true, features = ["regex"] }
2642

2743
[dev-dependencies]

crates/but-testsupport/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ use gix_testtools::{Creation, tempfile};
1313
mod in_memory_meta;
1414
pub use in_memory_meta::{InMemoryRefMetadata, InMemoryRefMetadataHandle, StackState};
1515

16+
#[cfg(feature = "sandbox")]
17+
mod sandbox;
18+
#[cfg(feature = "sandbox")]
19+
pub use sandbox::Sandbox;
20+
1621
/// Choose a slightly more obvious, yet easy to type syntax than a function with 4 parameters.
1722
/// i.e. `hunk_header("-1,10", "+1,10")`.
1823
/// Returns `( (old_start, old_lines), (new_start, new_lines) )`.

0 commit comments

Comments
 (0)