Files
storybook/src/lsp/formatting_tests.rs
Sienna Meridian Satterwhite 16deb5d237 release: Storybook v0.2.0 - Major syntax and features update
BREAKING CHANGES:
- Relationship syntax now requires blocks for all participants
- Removed self/other perspective blocks from relationships
- Replaced 'guard' keyword with 'if' for behavior tree decorators

Language Features:
- Add tree-sitter grammar with improved if/condition disambiguation
- Add comprehensive tutorial and reference documentation
- Add SBIR v0.2.0 binary format specification
- Add resource linking system for behaviors and schedules
- Add year-long schedule patterns (day, season, recurrence)
- Add behavior tree enhancements (named nodes, decorators)

Documentation:
- Complete tutorial series (9 chapters) with baker family examples
- Complete reference documentation for all language features
- SBIR v0.2.0 specification with binary format details
- Added locations and institutions documentation

Examples:
- Convert all examples to baker family scenario
- Add comprehensive working examples

Tooling:
- Zed extension with LSP integration
- Tree-sitter grammar for syntax highlighting
- Build scripts and development tools

Version Updates:
- Main package: 0.1.0 → 0.2.0
- Tree-sitter grammar: 0.1.0 → 0.2.0
- Zed extension: 0.1.0 → 0.2.0
- Storybook editor: 0.1.0 → 0.2.0
2026-02-13 21:52:03 +00:00

168 lines
4.3 KiB
Rust

//! Tests for LSP document formatting functionality
//!
//! This module tests auto-formatting for:
//! - Spacing normalization around colons
//! - Indentation preservation
//! - Prose block preservation
//! - Edge cases (empty documents, already formatted)
use tower_lsp::lsp_types::FormattingOptions;
use super::{
document::Document,
formatting::{
format_document,
format_text,
},
};
#[test]
fn test_format_adds_space_after_colon() {
let input = "character Alice{age:7}";
let formatted = format_text(input);
// Main formatting: adds space after colon
assert!(formatted.contains("age: 7"));
}
#[test]
fn test_format_normalizes_colon_spacing() {
let input = "character Alice{age : 7}";
let formatted = format_text(input);
// Should normalize to single space after colon
assert!(formatted.contains("age: 7"));
assert!(!formatted.contains("age :"));
}
#[test]
fn test_format_multiple_fields() {
let input = "character Alice{age:7\nname:\"Alice\"}";
let formatted = format_text(input);
assert!(formatted.contains("age: 7"));
assert!(formatted.contains("name: \"Alice\""));
}
#[test]
fn test_format_preserves_module_paths() {
let input = "use characters::Alice;";
let formatted = format_text(input);
// Should NOT add space in :: paths
assert!(formatted.contains("characters::Alice"));
assert!(!formatted.contains("characters: :Alice"));
}
#[test]
fn test_format_preserves_prose_blocks() {
let input = r#"character Alice{
---backstory
Some irregular spacing here
---
age:7}"#;
let formatted = format_text(input);
// Prose content preserved exactly
assert!(formatted.contains("Some irregular spacing here"));
// But other fields still formatted
assert!(formatted.contains("age: 7"));
}
#[test]
fn test_format_indentation_with_braces() {
let input = "character Alice{\nage:7\n}";
let formatted = format_text(input);
// Check indentation (4 spaces)
assert!(formatted.contains("character Alice{"));
assert!(formatted.contains(" age: 7"));
assert!(formatted.contains("}"));
}
#[test]
fn test_format_nested_indentation() {
let input = "template Person{\nnested:{\nvalue:123\n}\n}";
let formatted = format_text(input);
assert!(formatted.contains(" nested: {"));
assert!(formatted.contains(" value: 123"));
assert!(formatted.contains(" }"));
}
#[test]
fn test_format_empty_document() {
let input = "";
let formatted = format_text(input);
assert_eq!(formatted, "");
}
#[test]
fn test_format_whitespace_only() {
let input = " \n \n ";
let formatted = format_text(input);
// Should collapse to single newline or empty
assert!(formatted.len() <= 2);
}
#[test]
fn test_format_already_formatted() {
let input = "character Alice{\n age: 7\n}";
let formatted = format_text(input);
// Should remain essentially the same
assert!(formatted.contains("age: 7"));
}
#[test]
fn test_format_removes_multiple_blank_lines() {
let input = "character Alice{age:7}\n\n\n\ncharacter Bob{age:10}";
let formatted = format_text(input);
// Should consolidate multiple blank lines
let double_newlines = formatted.matches("\n\n\n").count();
assert_eq!(double_newlines, 0, "Should not have triple newlines");
}
#[test]
fn test_format_comments_unchanged() {
let input = "// Comment\ncharacter Alice{age:7}";
let formatted = format_text(input);
assert!(formatted.contains("// Comment"));
}
#[test]
fn test_format_document_returns_text_edit() {
let input = "character Alice{age:7}";
let doc = Document::new(input.to_string());
let result = format_document(&doc, &FormattingOptions::default());
if doc.ast.is_some() {
assert!(
result.is_some(),
"Should return TextEdit for valid document"
);
}
}
#[test]
fn test_format_document_no_changes_returns_none() {
let input = "character Alice{\n age: 7\n}\n";
let doc = Document::new(input.to_string());
let result = format_document(&doc, &FormattingOptions::default());
// If document is already formatted, may return None
// (depends on exact formatting match)
if result.is_none() {
assert!(
doc.ast.is_some(),
"Should only return None if formatting matches"
);
}
}