#+TITLE: sdp assertions
#+AUTHOR: Ralph Amissah
#+EMAIL: ralph.amissah@gmail.com
#+STARTUP: indent
#+LANGUAGE: en
#+OPTIONS: H:3 num:nil toc:t \n:nil @:t ::t |:t ^:nil _:nil -:t f:t *:t <:t
#+OPTIONS: TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc
#+OPTIONS: author:nil email:nil creator:nil timestamp:nil
#+PROPERTY: header-args :padline no :exports none :noweb yes
#+EXPORT_SELECT_TAGS: export
#+EXPORT_EXCLUDE_TAGS: noexport
#+FILETAGS: :sdp:rel:ao:
#+TAGS: assert(a) class(c) debug(d) mixin(m) sdp(s) tangle(T) template(t) WEB(W) noexport(n)

* assertions                                                   :mixin:assert:
[[./sdp.org][sdp]] [[./][org/]]
** mixin template: assertions on markup document structure    :doc_structure:
#+name: ao_assertions
#+BEGIN_SRC d
mixin template AssertionsOnMarkupDocumentStructure() {
  auto assertions_doc_structure(string[string] object, uint[string] lv) {
    if (lv["h3"] > 0) {
      assert(lv["h0"] > 0);
      assert(lv["h1"] > 0);
      assert(lv["h2"] > 0);
      assert(lv["h3"] > 0);
    } else if (lv["h2"] > 0) {
      assert(lv["h0"] > 0);
      assert(lv["h1"] > 0);
      assert(lv["h2"] > 0);
      assert(lv["h3"] == 0);
    } else if (lv["h1"] > 0) {
      assert(lv["h0"] > 0);
      assert(lv["h1"] > 0);
      assert(lv["h2"] == 0);
      assert(lv["h3"] == 0);
    } else if (lv["h0"] > 0) {
      assert(lv["h0"] > 0);
      assert(lv["h1"] == 0);
      assert(lv["h2"] == 0);
      assert(lv["h3"] == 0);
    } else {
      assert(lv["h0"] == 0);
      assert(lv["h1"] == 0);
      assert(lv["h2"] == 0);
      assert(lv["h3"] == 0);
    }
    if (lv["h7"] > 0) {
      assert(lv["h4"] > 0);
      assert(lv["h5"] > 0);
      assert(lv["h6"] > 0);
      assert(lv["h7"] > 0);
    } else if (lv["h6"] > 0) {
      assert(lv["h4"] > 0);
      assert(lv["h5"] > 0);
      assert(lv["h6"] > 0);
      assert(lv["h7"] == 0);
    } else if (lv["h5"] > 0) {
      assert(lv["h4"] > 0);
      assert(lv["h5"] > 0);
      assert(lv["h6"] == 0);
      assert(lv["h7"] == 0);
    } else if (lv["h4"] > 0) {
      assert(lv["h4"] > 0);
      assert(lv["h5"] == 0);
      assert(lv["h6"] == 0);
      assert(lv["h7"] == 0);
    } else {
      assert(lv["h4"] == 0);
      assert(lv["h5"] == 0);
      assert(lv["h6"] == 0);
      assert(lv["h7"] == 0);
    }
    if (lv["h0"] == 0) {
      assert(lv["h0"] == 0);
      assert(lv["h1"] == 0);
      assert(lv["h2"] == 0);
      assert(lv["h3"] == 0);
      assert(lv["h4"] == 0);
      assert(lv["h5"] == 0);
      assert(lv["h6"] == 0);
      assert(lv["h7"] == 0);
    }
    if (lv["h1"] == 0) {
      assert(lv["h1"] == 0);
      assert(lv["h2"] == 0);
      assert(lv["h3"] == 0);
    }
    if (lv["h2"] == 0) {
      assert(lv["h2"] == 0);
      assert(lv["h3"] == 0);
    }
    if (lv["h3"] == 0) {
      assert(lv["h3"] == 0);
    }
    if (lv["h4"] == 0) {
      assert(lv["h4"] == 0);
      assert(lv["h5"] == 0);
      assert(lv["h6"] == 0);
      assert(lv["h7"] == 0);
    }
    if (lv["h5"] == 0) {
      assert(lv["h5"] == 0);
      assert(lv["h6"] == 0);
      assert(lv["h7"] == 0);
    }
    if (lv["h6"] == 0) {
      assert(lv["h6"] == 0);
      assert(lv["h7"] == 0);
    }
    if (lv["h6"] == 0) {
      assert(lv["h7"] == 0);
    }
    switch (to!string(object["lev"])) {
    case "A":
      if (lv["h0"]==0) {
        assert(lv["h0"] == 0);
        assert(lv["h1"] == 0);
        assert(lv["h2"] == 0);
        assert(lv["h3"] == 0);
        assert(lv["h4"] == 0);
        assert(lv["h5"] == 0);
        assert(lv["h6"] == 0);
        assert(lv["h7"] == 0);
      } else {
        assert(lv["h0"] == 0,"error should not enter level A a second time");
      }
      break;
    case "B":
      if (lv["h1"]==0) {
        assert(lv["h0"] > 0);
        assert(lv["h1"] == 0); //
        assert(lv["h2"] == 0);
        assert(lv["h3"] == 0);
      } else {                 // (lv["h1"] >0)
        assert(lv["h0"] > 0);
        assert(lv["h1"] > 0);  //
      }
      break;
    case "C":
      if (lv["h2"]==0) {
        assert(lv["h0"] > 0);
        assert(lv["h1"] > 0);
        assert(lv["h2"] == 0); //
        assert(lv["h3"] == 0);
      } else {                 // (lv["h2"] > 0)
        assert(lv["h0"] > 0);
        assert(lv["h1"] > 0);
        assert(lv["h2"] > 0);  //
      }
      break;
    case "D":
      if (lv["h3"]==0) {
        assert(lv["h0"] > 0);
        assert(lv["h1"] > 0);
        assert(lv["h2"] > 0);
        assert(lv["h3"] == 0); //
      } else {                 // (lv["h3"] >0)
        assert(lv["h0"] > 0);
        assert(lv["h1"] > 0);
        assert(lv["h2"] > 0);
        assert(lv["h3"] > 0);
      }
      break;
    case "1":
      if (lv["h4"]==0) {
        assert(lv["h0"] > 0);
        assert(lv["h4"] == 0); //
      } else {                 // (lv["h4"] >0)
        assert(lv["h0"] > 0);
        assert(lv["h4"] > 0);  //
      }
      break;
    case "2":
      if (lv["h5"]==0) {
        assert(lv["h0"] > 0);
        assert(lv["h4"] > 0);
        assert(lv["h5"] == 0); //
      } else {                 // (lv["h5"] >0)
        assert(lv["h0"] > 0);
        assert(lv["h4"] > 0);
        assert(lv["h5"] > 0);  //
      }
      break;
    case "3":
      if (lv["h6"]==0) {
        assert(lv["h0"] > 0);
        assert(lv["h4"] > 0);
        assert(lv["h5"] > 0);
        assert(lv["h6"] == 0); //
      } else {                 // (lv["h6"] >0)
        assert(lv["h0"] > 0);
        assert(lv["h4"] > 0);
        assert(lv["h5"] > 0);
        assert(lv["h6"] > 0);  //
      }
      break;
    case "4":
      if (lv["h7"]==0) {
        assert(lv["h0"] > 0);
        assert(lv["h4"] > 0);
        assert(lv["h5"] > 0);
        assert(lv["h6"] > 0);
        assert(lv["h7"] == 0); //
      } else {                 // (lv["h7"] >0)
        assert(lv["h0"] > 0);
        assert(lv["h4"] > 0);
        assert(lv["h5"] > 0);
        assert(lv["h6"] > 0);
        assert(lv["h7"] > 0);  //
      }
      break;
    default:
      break;
    }
  }
}
#+END_SRC
** mixin template: assertions on blocks                              :blocks:
#+name: ao_assertions
#+BEGIN_SRC d
mixin template AssertionsOnBlocks() {
  auto assertions_flag_types_block_status_none_or_closed(int[string] flag_type) {
    assert(
      (flag_type["code"] == 0) || (flag_type["code"] == 2),
      "code block status: none or closed");
    assert(
      (flag_type["poem"] == 0) || (flag_type["poem"] == 2),
      "poem status: none or closed");
    assert(
      (flag_type["table"] == 0) || (flag_type["table"] == 2),
      "table status: none or closed");
    assert(
      (flag_type["group"] == 0) || (flag_type["group"] == 2),
      "group block status: none or closed");
    assert(
      (flag_type["block"] == 0) || (flag_type["block"] == 2),
      "block status: none or closed");
  }
}
#+END_SRC

* tangle                                                             :tangle:
** code structure:                                           :ao_assertions.d:
#+name: tangle_ao_assertions
#+BEGIN_SRC d :tangle ../lib/sdp/ao_assertions.d
/*
  assertions
  ao_assertions.d
*/
<<ao_assertions>>
#+END_SRC