285 lines
7.8 KiB
V
285 lines
7.8 KiB
V
module tests
|
|
|
|
import os
|
|
import builder
|
|
import config
|
|
|
|
fn test_build_graph_handles_empty_config() {
|
|
cfg := config.BuildConfig{
|
|
project_name: 'empty'
|
|
shared_libs: []
|
|
tools: []
|
|
}
|
|
|
|
summary := builder.preview_build_graph(&cfg) or { panic(err) }
|
|
|
|
assert summary.nodes.len == 0
|
|
assert summary.order.len == 0
|
|
}
|
|
|
|
fn test_build_graph_handles_multiple_dependencies() {
|
|
tmp := new_temp_dir('lana_multi_deps')
|
|
defer {
|
|
os.rmdir_all(tmp) or {}
|
|
}
|
|
|
|
src_dir := os.join_path(tmp, 'src')
|
|
lib_dir := os.join_path(src_dir, 'lib')
|
|
tool_dir := os.join_path(src_dir, 'tools')
|
|
os.mkdir_all(lib_dir) or { panic(err) }
|
|
os.mkdir_all(tool_dir) or { panic(err) }
|
|
|
|
// Create source files
|
|
os.write_file(os.join_path(lib_dir, 'base.cpp'), '// base') or { panic(err) }
|
|
os.write_file(os.join_path(lib_dir, 'utils.cpp'), '// utils') or { panic(err) }
|
|
os.write_file(os.join_path(lib_dir, 'core.cpp'), '// core') or { panic(err) }
|
|
os.write_file(os.join_path(tool_dir, 'app.cpp'), '// app') or { panic(err) }
|
|
|
|
// core depends on base and utils
|
|
// app depends on core
|
|
cfg := config.BuildConfig{
|
|
project_name: 'multi_deps'
|
|
src_dir: src_dir
|
|
shared_libs: [
|
|
config.SharedLibConfig{
|
|
name: 'base'
|
|
sources: [os.join_path(lib_dir, 'base.cpp')]
|
|
},
|
|
config.SharedLibConfig{
|
|
name: 'utils'
|
|
sources: [os.join_path(lib_dir, 'utils.cpp')]
|
|
},
|
|
config.SharedLibConfig{
|
|
name: 'core'
|
|
sources: [os.join_path(lib_dir, 'core.cpp')]
|
|
libraries: ['base', 'utils']
|
|
},
|
|
]
|
|
tools: [
|
|
config.ToolConfig{
|
|
name: 'app'
|
|
sources: [os.join_path(tool_dir, 'app.cpp')]
|
|
libraries: ['core']
|
|
},
|
|
]
|
|
}
|
|
|
|
summary := builder.preview_build_graph(&cfg) or { panic(err) }
|
|
|
|
// Should have 4 nodes
|
|
assert summary.nodes.len == 4
|
|
|
|
// Find app in order - it should come after core
|
|
mut core_idx := -1
|
|
mut app_idx := -1
|
|
for idx, id in summary.order {
|
|
if id == 'shared:core' {
|
|
core_idx = idx
|
|
}
|
|
if id == 'tool:app' {
|
|
app_idx = idx
|
|
}
|
|
}
|
|
|
|
assert core_idx >= 0
|
|
assert app_idx >= 0
|
|
assert app_idx > core_idx
|
|
|
|
// base and utils should come before core
|
|
mut base_idx := -1
|
|
mut utils_idx := -1
|
|
for idx, id in summary.order {
|
|
if id == 'shared:base' {
|
|
base_idx = idx
|
|
}
|
|
if id == 'shared:utils' {
|
|
utils_idx = idx
|
|
}
|
|
}
|
|
|
|
assert base_idx < core_idx
|
|
assert utils_idx < core_idx
|
|
}
|
|
|
|
fn test_build_graph_detects_unresolved_dependencies() {
|
|
tmp := new_temp_dir('lana_unresolved')
|
|
defer {
|
|
os.rmdir_all(tmp) or {}
|
|
}
|
|
|
|
src_dir := os.join_path(tmp, 'src')
|
|
os.mkdir_all(src_dir) or { panic(err) }
|
|
os.write_file(os.join_path(src_dir, 'main.cpp'), '// main') or { panic(err) }
|
|
|
|
cfg := config.BuildConfig{
|
|
project_name: 'unresolved'
|
|
src_dir: src_dir
|
|
tools: [
|
|
config.ToolConfig{
|
|
name: 'app'
|
|
sources: [os.join_path(src_dir, 'main.cpp')]
|
|
libraries: ['nonexistent_lib']
|
|
},
|
|
]
|
|
}
|
|
|
|
summary := builder.preview_build_graph(&cfg) or { panic(err) }
|
|
|
|
// Should have 1 node with unresolved dependency
|
|
assert summary.nodes.len == 1
|
|
assert 'tool:app' in summary.unresolved
|
|
assert summary.unresolved['tool:app'].contains('nonexistent_lib')
|
|
}
|
|
|
|
fn test_build_graph_skips_empty_sources() {
|
|
cfg := config.BuildConfig{
|
|
project_name: 'empty_sources'
|
|
debug: true
|
|
verbose: true
|
|
shared_libs: [
|
|
config.SharedLibConfig{
|
|
name: 'empty_lib'
|
|
sources: []
|
|
debug: true
|
|
},
|
|
]
|
|
tools: [
|
|
config.ToolConfig{
|
|
name: 'empty_tool'
|
|
sources: []
|
|
debug: true
|
|
},
|
|
]
|
|
}
|
|
|
|
summary := builder.preview_build_graph(&cfg) or { panic(err) }
|
|
|
|
// Empty sources should be skipped
|
|
assert summary.nodes.len == 0
|
|
}
|
|
|
|
fn test_build_graph_resolves_lib_prefix_aliases() {
|
|
tmp := new_temp_dir('lana_aliases')
|
|
defer {
|
|
os.rmdir_all(tmp) or {}
|
|
}
|
|
|
|
src_dir := os.join_path(tmp, 'src')
|
|
lib_dir := os.join_path(src_dir, 'lib')
|
|
tool_dir := os.join_path(src_dir, 'tools')
|
|
os.mkdir_all(lib_dir) or { panic(err) }
|
|
os.mkdir_all(tool_dir) or { panic(err) }
|
|
|
|
os.write_file(os.join_path(lib_dir, 'mylib.cpp'), '// lib') or { panic(err) }
|
|
os.write_file(os.join_path(tool_dir, 'app.cpp'), '// app') or { panic(err) }
|
|
|
|
// Reference library with lib/ prefix
|
|
cfg := config.BuildConfig{
|
|
project_name: 'aliases'
|
|
src_dir: src_dir
|
|
shared_libs: [
|
|
config.SharedLibConfig{
|
|
name: 'mylib'
|
|
sources: [os.join_path(lib_dir, 'mylib.cpp')]
|
|
},
|
|
]
|
|
tools: [
|
|
config.ToolConfig{
|
|
name: 'app'
|
|
sources: [os.join_path(tool_dir, 'app.cpp')]
|
|
libraries: ['lib/mylib']
|
|
},
|
|
]
|
|
}
|
|
|
|
summary := builder.preview_build_graph(&cfg) or { panic(err) }
|
|
|
|
// Dependency should be resolved
|
|
assert summary.nodes.len == 2
|
|
assert summary.unresolved.len == 0
|
|
|
|
// Find app node and check its dependencies
|
|
for node in summary.nodes {
|
|
if node.id == 'tool:app' {
|
|
assert node.dependencies.contains('shared:mylib')
|
|
}
|
|
}
|
|
}
|
|
|
|
fn test_build_graph_resolves_so_extension_aliases() {
|
|
tmp := new_temp_dir('lana_so_aliases')
|
|
defer {
|
|
os.rmdir_all(tmp) or {}
|
|
}
|
|
|
|
src_dir := os.join_path(tmp, 'src')
|
|
lib_dir := os.join_path(src_dir, 'lib')
|
|
tool_dir := os.join_path(src_dir, 'tools')
|
|
os.mkdir_all(lib_dir) or { panic(err) }
|
|
os.mkdir_all(tool_dir) or { panic(err) }
|
|
|
|
os.write_file(os.join_path(lib_dir, 'core.cpp'), '// lib') or { panic(err) }
|
|
os.write_file(os.join_path(tool_dir, 'app.cpp'), '// app') or { panic(err) }
|
|
|
|
// Reference library with .so extension
|
|
cfg := config.BuildConfig{
|
|
project_name: 'so_aliases'
|
|
src_dir: src_dir
|
|
shared_libs: [
|
|
config.SharedLibConfig{
|
|
name: 'core'
|
|
sources: [os.join_path(lib_dir, 'core.cpp')]
|
|
},
|
|
]
|
|
tools: [
|
|
config.ToolConfig{
|
|
name: 'app'
|
|
sources: [os.join_path(tool_dir, 'app.cpp')]
|
|
libraries: ['core.so']
|
|
},
|
|
]
|
|
}
|
|
|
|
summary := builder.preview_build_graph(&cfg) or { panic(err) }
|
|
|
|
// Dependency should be resolved
|
|
assert summary.unresolved.len == 0
|
|
|
|
for node in summary.nodes {
|
|
if node.id == 'tool:app' {
|
|
assert node.dependencies.contains('shared:core')
|
|
}
|
|
}
|
|
}
|
|
|
|
fn test_build_graph_includes_directives() {
|
|
tmp := new_temp_dir('lana_directives_graph')
|
|
defer {
|
|
os.rmdir_all(tmp) or {}
|
|
}
|
|
|
|
src_dir := os.join_path(tmp, 'src')
|
|
tool_dir := os.join_path(src_dir, 'tools')
|
|
os.mkdir_all(tool_dir) or { panic(err) }
|
|
|
|
os.write_file(os.join_path(tool_dir, 'custom.cpp'), '// custom') or { panic(err) }
|
|
|
|
cfg := config.BuildConfig{
|
|
project_name: 'directives'
|
|
src_dir: src_dir
|
|
build_directives: [
|
|
config.BuildDirective{
|
|
unit_name: 'tools/custom'
|
|
output_path: 'tools/custom'
|
|
is_shared: false
|
|
},
|
|
]
|
|
}
|
|
|
|
summary := builder.preview_build_graph(&cfg) or { panic(err) }
|
|
|
|
assert summary.nodes.len == 1
|
|
assert summary.nodes[0].id == 'directive:tools/custom'
|
|
assert summary.nodes[0].is_directive == true
|
|
}
|