Add another lightweight test.
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 6 Jan 2026 00:06:46 +0000 (16:06 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 6 Jan 2026 00:06:46 +0000 (16:06 -0800)
rust/pspp/src/spv/read/light.rs
rust/pspp/src/spv/read/tests.rs
rust/pspp/src/spv/testdata/light2.expected [new file with mode: 0644]
rust/pspp/src/spv/testdata/light2.spv [new file with mode: 0644]

index e603b589887482540d099d3b3e9c9a8ea94a3afe..2a2f4d8692f25ac72a366321dc169336f0266e9e 100644 (file)
@@ -14,7 +14,6 @@ use chrono::DateTime;
 use displaydoc::Display;
 use encoding_rs::{Encoding, WINDOWS_1252};
 use enum_map::{EnumMap, enum_map};
-use itertools::Itertools;
 
 use crate::{
     data::Datum,
@@ -255,7 +254,7 @@ impl LightTable {
                     }
                 }),
                 title: Some(Box::new(
-                    self.titles.title.decode(encoding, &footnotes, warn),
+                    self.titles.user_title.decode(encoding, &footnotes, warn),
                 )),
                 subtype: Some(Box::new(
                     self.titles.subtype.decode(encoding, &footnotes, warn),
@@ -1762,7 +1761,6 @@ impl Axes {
     ) -> Result<Vec<(Axis3, pivot::Dimension)>, (LightWarning, Vec<pivot::Dimension>)> {
         let n = self.layers.len() + self.rows.len() + self.columns.len();
         if n != dimensions.len() {
-            // Warn, then treat all of the dimensions as rows.
             return Err((
                 LightWarning::WrongAxisCount {
                     expected: dimensions.len(),
@@ -1779,19 +1777,34 @@ impl Axes {
             dimensions.iter().map(move |d| (axis, *d as usize))
         }
 
-        let mut axes = vec![None; n];
+        let mut dimensions = dimensions.into_iter().map(Some).collect::<Vec<_>>();
+        let mut output = Vec::with_capacity(n);
+
         for (axis, index) in axis_dims(Axis3::Z, &self.layers)
             .chain(axis_dims(Axis3::Y, &self.rows))
             .chain(axis_dims(Axis3::X, &self.columns))
         {
-            if index >= n {
-                return Err((LightWarning::InvalidDimensionIndex { index, n }, dimensions));
-            } else if axes[index].is_some() {
-                return Err((LightWarning::DuplicateDimensionIndex(index), dimensions));
+            let result = dimensions
+                .get_mut(index)
+                .ok_or(LightWarning::InvalidDimensionIndex { index, n })
+                .and_then(|dimension| {
+                    dimension
+                        .take()
+                        .ok_or(LightWarning::DuplicateDimensionIndex(index))
+                });
+            match result {
+                Ok(dimension) => output.push((axis, dimension)),
+                Err(error) => {
+                    let dimensions = dimensions
+                        .into_iter()
+                        .flatten()
+                        .chain(output.into_iter().map(|(_axis, dimension)| dimension))
+                        .collect();
+                    return Err((error, dimensions));
+                }
             }
-            axes[index] = Some(axis);
         }
-        Ok(axes.into_iter().flatten().zip_eq(dimensions).collect())
+        Ok(output)
     }
 }
 
index 57e24a961ce7bd16c065e5d2d0b3def6ec8574f4..bda6783e94848fc4c8508ee3a71065754f5115fa 100644 (file)
@@ -13,11 +13,19 @@ use crate::{
     spv::SpvArchive,
 };
 
+/// Checks that reordering categories works properly.
 #[test]
 fn light1() {
     test_raw_spvfile("light1", None);
 }
 
+/// Checks that dimensions are ordered properly and that the title reflects the
+/// user's changes.
+#[test]
+fn light2() {
+    test_raw_spvfile("light2", None);
+}
+
 #[test]
 fn legacy1() {
     test_raw_spvfile("legacy1", None);
diff --git a/rust/pspp/src/spv/testdata/light2.expected b/rust/pspp/src/spv/testdata/light2.expected
new file mode 100644 (file)
index 0000000..5650a27
--- /dev/null
@@ -0,0 +1,24 @@
+                        Crosstabulation
+╭──────────────────────────────┬───────────────────────┬──────╮
+│                              │       Variable B      │      │
+│                              ├──────┬────────┬───────┤      │
+│                              │Normal│Marginal│Extreme│ Total│
+├──────────────────────────────┼──────┼────────┼───────┼──────┤
+│Variable A Less Count         │    10│     7.0│  45.5%│ 52.6%│
+│                Expected Count│ 18.2%│   20.0%│   6.7%│    22│
+│                % within A    │ 15.0%│      13│   13.3│ 34.2%│
+│                % within B    │  38.0│  100.0%│  63.3%│ 63.3%│
+│                % of Total    │100.0%│   35.0%│     20│  20.0│
+│          ╶───────────────────┼──────┼────────┼───────┼──────┤
+│           More Count         │ 16.7%│       8│    7.7│ 36.4%│
+│                Expected Count│  22.0│  100.0%│  36.7%│ 36.7%│
+│                % within A    │ 61.9%│   21.7%│     16│  12.7│
+│                % within B    │    19│    19.0│  31.7%│100.0%│
+│                % of Total    │ 33.3%│  100.0%│  33.3%│    60│
+├──────────────────────────────┼──────┼────────┼───────┼──────┤
+│Total           Count         │ 38.1%│   13.3%│      4│   7.3│
+│                Expected Count│     9│    12.0│  23.7%│ 47.4%│
+│                % within A    │ 42.1%│   80.0%│  26.7%│    38│
+│                % within B    │ 31.7%│      21│   21.0│ 35.0%│
+│                % of Total    │  60.0│  100.0%│ 100.0%│100.0%│
+╰──────────────────────────────┴──────┴────────┴───────┴──────╯
diff --git a/rust/pspp/src/spv/testdata/light2.spv b/rust/pspp/src/spv/testdata/light2.spv
new file mode 100644 (file)
index 0000000..9e9210c
Binary files /dev/null and b/rust/pspp/src/spv/testdata/light2.spv differ