scroll.server/titan/titan/tests/csv.rs
scroll 812052bc3e initial import, client gets to the lobby
titan engine, logic model, auth/game/gateway services.
csv tables pulled out of the ipa are checked in so it runs out of the box.
2026-08-23 07:50:31 +03:00

90 lines
3.5 KiB
Rust

use titan::csv::{ColumnType, CsvNode, CsvReader};
const SPELLS: &str = concat!(
"Name,Rarity,Mana,SummonCharacter,Damage,Enabled\n",
"string,string,int,string,int,boolean\n",
"Knight,Common,3,Knight,75,true\n",
",,,,82,\n",
",,,,90,\n",
"Archers,Common,3,Archer,42,true\n",
",,,,46,\n",
"\"Mini P.E.K.K.A\",Rare,4,MiniPekka,325,false\n"
);
#[test]
fn the_first_two_lines_declare_names_and_types() {
let table = CsvReader::parse("spells_characters.csv", SPELLS).expect("parse");
assert_eq!(table.column_count(), 6);
assert_eq!(table.column_name(0), "Name");
assert_eq!(table.column_type(0), Some(ColumnType::String));
assert_eq!(table.column_type(2), Some(ColumnType::Int));
assert_eq!(table.column_type(5), Some(ColumnType::Boolean));
assert_eq!(table.column_index("Damage"), Some(4));
}
#[test]
fn a_row_opens_only_when_the_first_column_is_populated() {
let table = CsvReader::parse("spells_characters.csv", SPELLS).expect("parse");
assert_eq!(table.row_count(), 3);
assert_eq!(table.row_at(0).unwrap().string(0), "Knight");
assert_eq!(table.row_at(1).unwrap().string(0), "Archers");
assert_eq!(table.row_at(2).unwrap().string(0), "Mini P.E.K.K.A");
}
#[test]
fn continuation_lines_extend_the_per_level_arrays() {
let table = CsvReader::parse("spells_characters.csv", SPELLS).expect("parse");
let knight = table.row_at(0).expect("knight");
assert_eq!(knight.array_size(), 3);
assert_eq!(knight.value_count(4), 3);
assert_eq!(knight.int_at(4, 0), 75);
assert_eq!(knight.int_at(4, 1), 82);
assert_eq!(knight.int_at(4, 2), 90);
assert_eq!(knight.scaled_int(4, 9), 90);
assert_eq!(knight.int(2), 3);
assert!(knight.boolean(5));
let archers = table.row_at(1).expect("archers");
assert_eq!(archers.value_count(4), 2);
assert!(!table.row_at(2).unwrap().boolean(5));
}
#[test]
fn rows_are_addressable_by_their_first_column() {
let table = CsvReader::parse("spells_characters.csv", SPELLS).expect("parse");
assert_eq!(table.row_index_of("Archers"), Some(1));
assert_eq!(
table.row_by_name("Mini P.E.K.K.A").map(|row| row.int(2)),
Some(4)
);
assert!(table.row_by_name("Golem").is_none());
}
#[test]
fn quoted_cells_keep_their_commas() {
let source = concat!(
"Name,Text\n",
"string,string\n",
"Greeting,\"hello, world\"\n",
"Quote,\"say \"\"hi\"\"\"\n"
);
let table = CsvReader::parse("hints.csv", source).expect("parse");
assert_eq!(table.row_at(0).unwrap().string(1), "hello, world");
assert_eq!(table.row_at(1).unwrap().string(1), "say \"hi\"");
}
#[test]
fn missing_trailing_cells_decode_as_empty() {
let source = concat!("Name,A,B\n", "string,int,int\n", "Row,5\n");
let table = CsvReader::parse("t.csv", source).expect("parse");
let row = table.row_at(0).expect("row");
assert_eq!(row.int(1), 5);
assert_eq!(row.int(2), 0);
assert!(row.value(2).expect("value").is_empty());
}
#[test]
fn an_unknown_column_type_is_rejected() {
let source = concat!("Name,A\n", "string,float\n", "Row,1\n");
let error = CsvReader::parse("bad.csv", source).expect_err("must fail");
assert!(error.to_string().contains("float"));
}
#[test]
fn a_node_wraps_the_table_with_its_file_identity() {
let node = CsvNode::load("csv_logic/spells_characters.csv", SPELLS).expect("load");
assert_eq!(node.name(), "spells_characters");
assert_eq!(node.file_name(), "csv_logic/spells_characters.csv");
assert_eq!(node.table().row_count(), 3);
assert_eq!(node.node_count(), 0);
}