chiark / gitweb /
jstest: Programattically generate a test csase, wip
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 8 Jul 2021 20:16:52 +0000 (21:16 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 9 Jul 2021 00:19:50 +0000 (01:19 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Cargo.lock
jstest/Cargo.toml
jstest/jst-lower.rs
jstest/jstest.rs
jstest/lower.nodejs
src/imports.rs

index a22ed55a50c43a56e9943e69ebb8c09677b3a00d..be9cdf3d2987785f03943c0cc668d0b11ebbce4e 100644 (file)
@@ -2567,6 +2567,8 @@ dependencies = [
  "fehler",
  "indexmap",
  "otter",
+ "otter-api-tests",
+ "serde",
  "structopt",
 ]
 
index ef376d6b444e35f2dc3b3806b6c9a6c59f022545..d2ea72711e85c56cc23e0bbe057b258d0b5e9754 100644 (file)
@@ -29,12 +29,15 @@ path="jst-lower.rs"
 otter.path=".."
 otter.version="=0.7.1"
 
+otter-api-tests.path="../apitest"
+otter-api-tests.version="=0.7.1"
+
 indexmap = "1.6"
 
 fehler="1"
 structopt="0.3"
 
-#serde        = { version="1"    , features=["derive", "rc"] }
+serde        = { version="1"    , features=["derive", "rc"] }
 #strum        = { version="0.21" , features=["derive"      ] }
 
 
index a75b594a034b47e8d8eb0788b4fb1b0247ac7bb8..26a7352d142b7f2a7b9e9f01a9360e970b890b25 100644 (file)
@@ -27,6 +27,7 @@ macro_rules! sp {
 
 #[derive(Debug,Clone)]
 #[derive(Eq,PartialEq,Ord,PartialOrd)]
+#[derive(Serialize)]
 pub struct StartPiece {
   id: String,
   pinned: bool,
@@ -36,11 +37,99 @@ pub struct StartPiece {
 
 #[derive(Debug,Clone,Default)]
 pub struct Tests {
-  tests: IndexMap<String, Vec<StartPiece>>,
+  tests: IndexMap<String, Test>,
 }
 
-impl Tests {
-  pub fn add_test(&mut self, name: &'static str, pieces: Vec<StartPieceSpec>) {
+#[derive(Debug,Clone,Default)]
+#[derive(Serialize)]
+pub struct Test {
+  name: String,
+  pieces: Vec<StartPiece>,
+  targets: Vec<String>,
+}
+
+#[derive(Debug)]
+pub struct TestsAccumulator {
+  tests: Tests,
+  script: BufWriter<fs::File>,
+  tera: tera::Tera,
+}
+
+static TEMPLATE: &'static str = r#"
+//-------------------- {{ name }} --------------------
+
+jstest_did = fs.openSync('{{ name }}.did', 'w');
+
+pieces = {
+{% for p in pieces %}
+  '{{ p.id }}': {
+    pinned: {{ p.pinned }},
+    moveable: '{{ p.moveable }}',
+    z: '{{ p.z }}',
+  },
+{% endfor %}
+}
+
+fake_dom = [
+  { special: "pieces_marker", dataset: { } },
+{% for p in pieces %}
+  { dataset: { piece: "{{ p.id }}" } },
+{% endfor %}
+  { special: "defs_marker", dataset: { } },
+];
+
+pieces_marker = fake_dom[0];
+defs_marker   = fake_dom[{{ pieces | length + 1 }}];
+
+{% for p in pieces %}
+fake_dom[{{ loop.index0 }}].nextElementSibling = fake_dom[{{ loop.index }}];
+{% endfor %}
+fake_dom[{{ pieces | length }}].nextElementSibling = fake_dom[{{ pieces | length + 1 }}];
+
+{% for t in targets %}
+uorecord = {
+  targets: ['{{ t }}'],
+};
+{% endfor %}
+
+lower_targets(uorecord);
+
+fs.closeSync(jstest_did);
+jstest_did = -1;
+
+"#;
+
+
+impl TestsAccumulator {
+  #[throws(Explode)]
+  pub fn new(opts: &Opts) -> Self {
+    let mut tera = tera::Tera::default();
+    tera.add_raw_template("js", TEMPLATE)?;
+
+    let script = fs::OpenOptions::new()
+      .write(true)
+      .append(true)
+      .truncate(false)
+      .create(false)
+      .open(&opts.script)?;
+    let script = BufWriter::new(script);
+
+    TestsAccumulator {
+      tests: default(),
+      script, tera,
+    }
+  }
+
+  #[throws(Explode)]
+  pub fn finalise(mut self) -> Tests {
+    self.script.flush()?;
+    self.tests
+  }
+    
+  #[throws(Explode)]
+  pub fn add_test(&mut self, name: &'static str,
+                  pieces: Vec<StartPieceSpec>,
+                  targets: Vec<&'_ str>) {
     let mut zm = ZCoord::default().clone_mut();
     let pieces = pieces.into_iter().map(
       |StartPieceSpec { id, pinned, moveable }| {
@@ -49,20 +138,36 @@ impl Tests {
         StartPiece { id, pinned, moveable, z }
       }
     ).collect_vec();
-    let already = self.tests.insert(name.to_owned(), pieces);
-    assert_eq!(already, None);
+
+    let targets = targets.into_iter().map(|s| s.to_owned()).collect_vec();
+
+    let test = Test {
+      name: name.into(),
+      pieces, targets,
+    };
+    let context = tera::Context::from_serialize(&test)?;
+    self.tera.render_to("js", &context, &mut self.script)?;
+
+    let already = self.tests.tests.insert(name.to_owned(), test);
+    assert!(already.is_none(), "{:?}", &name);
   }
 }
 
-#[throws(AE)]
+#[throws(Explode)]
 fn main() {
   let opts = Opts::from_args();
 
-  let mut tests = Tests::default();
-  tests.add_test("simple", vec![
+  let mut ta = TestsAccumulator::new(&opts)?;
+
+  ta.add_test("simple", vec![
     sp!("1.1", false, Yes),
     sp!("2.1", false, Yes),
-  ]);
+  ], vec![
+    "2.1",
+  ])?;
+
+  let tests = ta.finalise()?;
+  eprintln!("TESTS={:?}", &tests);
 
   let mut cmd = Command::new(opts.nodejs);
   cmd.arg(opts.script);
index a077b6a1140b589f9f94647c9958b51df60df730..74de17d45e7f21c6e74896c112e166548f23811b 100644 (file)
@@ -4,5 +4,8 @@
 
 pub use otter::prelude::*;
 
+pub use otter_api_tests::Explode;
+pub use otter::imports::tera_standalone as tera;
+
 pub use indexmap::IndexMap;
 pub use structopt::StructOpt;
index 1bc56a494249a7994aedce3cb1d291eeefc8df74..d69f4728c70e720ad1341aa7662df95e40f52559 100644 (file)
@@ -11,6 +11,8 @@ let wasm_bindgen = require('otter_wasm.js');
 
 
 let jstest_did;
+let fake_dom;
+let uorecord;
 
 function piece_set_zlevel(piece, p, f) { f(null); }
 function api_piece(op, piece, p, args) {
@@ -34,7 +36,7 @@ pieces = {
   },
 }
 
-let fake_dom = [
+fake_dom = [
   { special: "pieces_marker", dataset: { } },
   { dataset: { piece: "1.1" } },
   { dataset: { piece: "2.1" } },
@@ -48,7 +50,7 @@ fake_dom[0].nextElementSibling = fake_dom[1];
 fake_dom[1].nextElementSibling = fake_dom[2];
 fake_dom[2].nextElementSibling = fake_dom[3];
 
-let uorecord = {
+uorecord = {
   targets: ["2.1"],
 };
 
index 3baa6e548c95cabf9d1cb92a09438b4530763c39..450d3cc0a94c2a1056096558efd592571c0d0d25 100644 (file)
@@ -34,6 +34,7 @@ pub use regex;
 pub use rmp_serde;
 pub use sha2;
 pub use slotmap;
+pub use tera_standalone;
 pub use toml;
 pub use uds;
 pub use unicode_width;