use super::render_go_mod;
#[test]
fn render_go_mod_without_extras() {
let out = render_go_mod("github.com/example/mylib", None, "v1.0.0", None);
assert!(
out.contains("github.com/example/mylib v1.0.0"),
"should contain main module require"
);
assert!(
out.contains("github.com/stretchr/testify v1.11.1"),
"should contain testify require"
);
assert!(
!out.contains("github.com/tree-sitter"),
"should not contain tree-sitter without extras"
);
}
#[test]
fn render_go_mod_includes_testify_indirect_deps() {
let out = render_go_mod("github.com/example/mylib", None, "v1.0.0", None);
for indirect in [
"github.com/davecgh/go-spew v1.1.1 // indirect",
"github.com/pmezard/go-difflib v1.0.0 // indirect",
"gopkg.in/yaml.v3 v3.0.1 // indirect",
] {
assert!(
out.contains(indirect),
"go.mod must contain testify indirect dep `{indirect}`, got:\n{out}"
);
}
}
#[test]
fn render_go_mod_registry_mode_uses_sibling_module_path() {
let out = render_go_mod("github.com/example/mylib", None, "v1.0.0", None);
assert!(
out.contains("module github.com/example/mylib-e2e"),
"registry-mode main module must be a sibling path, got: {out}"
);
assert!(
!out.contains("module github.com/example/mylib/e2e"),
"registry-mode main module must not shadow the module under test, got: {out}"
);
}
#[test]
fn render_go_mod_local_mode_uses_nested_module_path() {
let out = render_go_mod("github.com/example/mylib", Some("../../packages/go"), "v0.0.0", None);
assert!(
out.contains("module github.com/example/mylib/e2e"),
"local-mode main module should stay nested, got: {out}"
);
}
#[test]
fn render_go_mod_with_extras_includes_requires() {
use crate::core::config::manifest_extras::{ExtraDepSpec, ManifestExtras};
let mut extras = ManifestExtras::default();
extras.dev_dependencies.insert(
"github.com/tree-sitter/go-tree-sitter".to_string(),
ExtraDepSpec::Simple("v0.24.0".to_string()),
);
let out = render_go_mod("github.com/example/mylib", None, "v1.0.0", Some(&extras));
assert!(
out.contains("github.com/tree-sitter/go-tree-sitter v0.24.0"),
"should include tree-sitter extra, got: {out}"
);
assert!(
out.contains("github.com/example/mylib v1.0.0"),
"should still contain main module"
);
}
#[test]
fn render_go_mod_extras_with_replace_directive() {
use crate::core::config::manifest_extras::{ExtraDepSpec, ManifestExtras};
let mut extras = ManifestExtras::default();
extras.dependencies.insert(
"github.com/upstream/lib".to_string(),
ExtraDepSpec::Simple("v0.5.0".to_string()),
);
let out = render_go_mod(
"github.com/example/mylib",
Some("../../packages/go"),
"v0.0.0",
Some(&extras),
);
assert!(
out.contains("github.com/upstream/lib v0.5.0"),
"should include upstream lib"
);
assert!(
out.contains("replace github.com/example/mylib => ../../packages/go"),
"should include replace directive"
);
}
#[test]
fn render_go_mod_empty_extras_matches_no_extras() {
use crate::core::config::manifest_extras::ManifestExtras;
let extras = ManifestExtras::default();
let without_empty = render_go_mod("github.com/example/mylib", None, "v1.0.0", None);
let with_empty = render_go_mod("github.com/example/mylib", None, "v1.0.0", Some(&extras));
assert_eq!(without_empty, with_empty, "empty extras should be equivalent to None");
}
#[test]
fn render_go_mod_extras_are_sorted_deterministically() {
use crate::core::config::manifest_extras::{ExtraDepSpec, ManifestExtras};
let mut extras = ManifestExtras::default();
extras.dev_dependencies.insert(
"github.com/z-last/lib".to_string(),
ExtraDepSpec::Simple("v1.0.0".to_string()),
);
extras.dev_dependencies.insert(
"github.com/a-first/lib".to_string(),
ExtraDepSpec::Simple("v2.0.0".to_string()),
);
extras.dependencies.insert(
"github.com/m-middle/lib".to_string(),
ExtraDepSpec::Simple("v3.0.0".to_string()),
);
let out = render_go_mod("github.com/example/mylib", None, "v1.0.0", Some(&extras));
let first_idx = out.find("github.com/a-first/lib").expect("should find a-first");
let middle_idx = out.find("github.com/m-middle/lib").expect("should find m-middle");
let last_idx = out.find("github.com/z-last/lib").expect("should find z-last");
assert!(
first_idx < middle_idx && middle_idx < last_idx,
"extras should be sorted alphabetically: {out}"
);
}
#[test]
fn render_go_mod_extras_handles_detailed_form_with_version() {
use crate::core::config::manifest_extras::{ExtraDepSpec, ManifestExtras};
let mut extras = ManifestExtras::default();
let mut table = toml::Table::new();
table.insert("version".to_string(), toml::Value::String("v0.25.0".to_string()));
table.insert("features".to_string(), toml::Value::String("debug".to_string()));
extras.dev_dependencies.insert(
"github.com/example/with-features".to_string(),
ExtraDepSpec::Detailed(table),
);
let out = render_go_mod("github.com/example/mylib", None, "v1.0.0", Some(&extras));
assert!(
out.contains("github.com/example/with-features v0.25.0"),
"should extract version from detailed form, got: {out}"
);
}
#[test]
fn render_go_mod_extras_skips_entries_without_version() {
use crate::core::config::manifest_extras::{ExtraDepSpec, ManifestExtras};
let mut extras = ManifestExtras::default();
let mut table = toml::Table::new();
table.insert(
"git".to_string(),
toml::Value::String("https://example.com".to_string()),
);
extras.dev_dependencies.insert(
"github.com/example/no-version".to_string(),
ExtraDepSpec::Detailed(table),
);
let out = render_go_mod("github.com/example/mylib", None, "v1.0.0", Some(&extras));
assert!(
!out.contains("github.com/example/no-version"),
"should skip extras without version field, got: {out}"
);
}
#[test]
fn render_go_mod_extras_idempotent() {
use crate::core::config::manifest_extras::{ExtraDepSpec, ManifestExtras};
let mut extras = ManifestExtras::default();
extras.dev_dependencies.insert(
"github.com/tree-sitter/go-tree-sitter".to_string(),
ExtraDepSpec::Simple("v0.24.0".to_string()),
);
let first = render_go_mod("github.com/example/mylib", None, "v1.0.0", Some(&extras));
let second = render_go_mod("github.com/example/mylib", None, "v1.0.0", Some(&extras));
assert_eq!(first, second, "re-rendering with same extras should be stable");
}