{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `importnb` test specification\n",
    "\n",
    "this notebook is written to test many of the features of `importnb`.\n",
    "\n",
    "these features in this notebook test:\n",
    "* basic finding and loading\n",
    "* filtering magics, classes and functions\n",
    "* lazy loading\n",
    "* the command line interface"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## a sentinel for execution"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "the `slug` below is used to measure that a module has been executed,\n",
    "we specifically use this expression to measure the lazy importing system."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i was printed from  and my name is __main__\n"
     ]
    }
   ],
   "source": [
    "from importnb import get_ipython\n",
    "from pathlib import Path\n",
    "where = \"\"\n",
    "if \"__file__\" in locals():\n",
    "    where = Path(__file__).as_posix()\n",
    "\n",
    "slug = \"i was printed from {where} \\\n",
    "and my name is {__name__}\"\n",
    "print(slug.format(**locals()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## implicit markdown docstrings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "there is a strict separation of code and non-code in notebooks.\n",
    "to encourage more/better documentation `importnb` will use a markdown\n",
    "cell preceeding a function as a docstring. \n",
    "as a result, the `function_with_a_markdown` docstring will have this markdown cell for a value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def function_with_a_markdown_docstring():\n",
    "    return # function_with_a_markdown has a docstring defined by the preceeding markdown cell"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "the same convention holds for classes and async functions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class class_with_a_markdown_docstring:\n",
    "    ... # my docstring is the cell above.        "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "this is not a docstring for `class_with_a_string` because it defines its own."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class class_with_a_python_docstring:\n",
    "    \"\"\"when a class defines its own docstring the preceeding cell is ignored.\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## cell magics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i'm only show when cell magics are active.\n"
     ]
    }
   ],
   "source": [
    "%%python\n",
    "print(\"i'm only show when cell magics are active.\", sep=\"\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "if get_ipython():\n",
    "    magic_slug = \"i'm only show when cell magics are active.\"\n",
    "else:\n",
    "    magic_slug = f\"this was printed from the module named {__name__}\"\n",
    "    print(magic_slug)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## notebooks as scripts"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "the main block is a python convention we can apply in notebooks imported by importnb."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_parser():\n",
    "    from argparse import ArgumentParser, REMAINDER\n",
    "    parser =  ArgumentParser(\"test_parser\")\n",
    "    parser.add_argument(\"--\", nargs=REMAINDER, dest=\"args\")\n",
    "    return parser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def main(argv=None):\n",
    "    parser = get_parser()\n",
    "    print(\"the parser namespace is\", parser.parse_args(argv))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### notebooks as `doit` tasks\n",
    "\n",
    "[`doit`](https://pydoit.org/) is powerful alternative to makefiles for running development tasks.\n",
    "the `importnb` command line provides support for `doit` conventions, but does not provide the dependency;\n",
    "you the `doit` are responsible for that."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "this the docstring for the `echo` task that echos hello."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def task_echo():\n",
    "    return dict(actions=[\"echo hello\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "if __name__ == \"__main__\":\n",
    "    if \"__file__\" in locals():\n",
    "        # run this notebook like it is a cli\n",
    "        if \"pytest\" not in sys.modules:\n",
    "            if \"doit\" not in sys.modules:\n",
    "                main(sys.argv[1:])\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": {
       "cell_type": null,
       "cells": null,
       "source": {},
       "text": null
      },
      "text/plain": [
       "<IPython.core.display.JSON object>"
      ]
     },
     "metadata": {
      "application/json": {
       "expanded": false,
       "root": "root"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "if get_ipython() and \"__file__\" not in locals():\n",
    "    from IPython.display import JSON\n",
    "    data = dict.fromkeys(\"cell_type source text cells\".split())\n",
    "    data[\"source\"] = {}\n",
    "    display(JSON(data))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:root] *",
   "language": "python",
   "name": "conda-root-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  },
  "vscode": {
   "interpreter": {
    "hash": "fe3da9b82b3647283ed4a64afb514c08b1aa39774194ba3fa7469a9333d7260c"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
