{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "authorship_tag": "ABX9TyOzDBKIih8xWpPX7WzJCSzw",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/Jaciss/jai/blob/main/notebooks/bdd_testing_a_notebook.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# this must happen before %run as they might use these dirs\n",
        "!mkdir -p features\n",
        "!mkdir -p features/steps"
      ],
      "metadata": {
        "id": "D8_SRlSuwF0g"
      },
      "execution_count": 1,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# import jai.nbpy.bootstrap # that too, as expected; no functions, though. some printing no logging even and no config passing"
      ],
      "metadata": {
        "id": "LyzWyRjYfyEG"
      },
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# c['private_config']='TESTING'\n",
        "# del c['private_config']\n",
        "# %run {c['nb_dir']}encrypted_private_config.ipynb"
      ],
      "metadata": {
        "id": "eOW2oVsq4Wi5"
      },
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "tCDRLNFp2l5z",
        "outputId": "bb3e1002-3873-4430-f307-87c3da1679fc"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Mounted at /content/drive/\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "2023-01-08 03:00:05 INFO     bdd_testing_a_notebook@bootstrap_a_notebook [/usr/local/lib/python3.8/dist-packages/ipykernel_launcher.py]\n",
            "2023-01-08 03:00:05 INFO     bdd_testing_a_notebook@bdd_testing_a_notebook\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing features/bootstrap_a_notebook.feature\n",
            "bootstrap_a_notebook functions:\n",
            "No variables match your requested type.\n"
          ]
        }
      ],
      "source": [
        "# basic config and bootstrapping all notebooks have\n",
        "import os.path\n",
        "from google.colab import drive\n",
        "\n",
        "nb_name = 'bdd_testing_a_notebook'\n",
        "try:\n",
        "  c # try to get config (from remote call)\n",
        "  c['nb_run_by'] = c.get('nb_name',None) # who is running the nb\n",
        "  c['nb_name'] = nb_name # nb_name set to local until end\n",
        "  nb_convert_bootstrap = False\n",
        "except NameError:\n",
        "  c = {'nb_name':nb_name, 'nb_run_by':nb_name, 'nb_dir':'drive/MyDrive/Colab\\ Notebooks/'} # if local set c\n",
        "  if not os.path.isdir('/content/drive/'): drive.mount('/content/drive/')\n",
        "  %run {c['nb_dir']}bootstrap_a_notebook.ipynb\n",
        "  nb_convert_bootstrap = True \n",
        "\n",
        "logger.info(c.get('nb_run_by',None)+'@'+c.get('nb_name',None)) #+' ['+sys.argv[0]+']')"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Functions"
      ],
      "metadata": {
        "id": "DczOELrffEVV"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# null common magics to run converted notebooks without ipython\n",
        "# WARNING: this will cause problems if you use magics for \"real\" functionality\n",
        "# e.g., things like `%pip install` should be handled via `-r requirements.txt`\n",
        "# use `replace('get_ipython().system','os.system')` so !commands work\n",
        "nb_convert_py_prepend = '''\n",
        "# WARNING: this file is automatically generated, changes will be overwritten\n",
        "import os\n",
        "import sys\n",
        "import logging\n",
        "logger = logging.getLogger()\n",
        "if \"ipykernel_launcher\" not in sys.argv[0]:\n",
        "  logger.warning(\"get_ipython() CALLS WILL RETURN '' (empty)\")\n",
        "  class get_ipython():\n",
        "    @classmethod\n",
        "    def system(one,two=None,three=None,four=None):\n",
        "      return os.system(two)\n",
        "    @classmethod\n",
        "    def run_cell_magic(one,two=None,three=None,four=None):\n",
        "      return ''\n",
        "    @classmethod\n",
        "    def getoutput(one,two):\n",
        "      return ''\n",
        "    @classmethod\n",
        "    def run_line_magic(one,two,three):\n",
        "      return ''\n",
        "'''"
      ],
      "metadata": {
        "id": "t6i2kRdxhIAi"
      },
      "execution_count": 5,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def get_module_name(nb_name):\n",
        "  mod_remove = ['a','notebook','with']\n",
        "  return ' '.join([word for word in nb_name.split('_') if word not in mod_remove]).replace(' ','')\n",
        "\n",
        "# notebooks have %%writefile for tests, need to write the py file to avoid module not found\n",
        "def nb_convert_py(nb_name):\n",
        "  module_name = get_module_name(nb_name)+'.py'\n",
        "  command = 'jupyter nbconvert --to python --output-dir jai/nbpy --output '+module_name+' '+c['nb_dir']+nb_name+'.ipynb'\n",
        "  os.system(command)\n",
        "  module_name = 'jai/nbpy/'+module_name\n",
        "  print()\n",
        "  # insert ipython nullification\n",
        "  with open(module_name, \"r\") as fi:\n",
        "    ti = fi.readlines()\n",
        "    ti.insert(3, str(nb_convert_py_prepend)) #prepend into test/python file\n",
        "  with open(module_name, \"w\") as fo:\n",
        "    to = ''.join(ti).replace('get_ipython().system','os.system')\n",
        "    fo.writelines(to.replace('\\n\\n','\\n'))\n",
        "  return module_name\n",
        "\n",
        "def test_notebook(nb_to_test:str='.'):\n",
        "  print('test_notebook()',nb_to_test,'run by',c['nb_run_by'],'self:',sys.argv[0])\n",
        "  if nb_to_test=='.': module_name = nb_convert_py(c['nb_run_by'])\n",
        "  else: module_name = nb_convert_py(nb_to_test)\n",
        "  if c['nb_run_by'] not in sys.argv[0] and \"ipykernel_launcher\" in sys.argv[0]:\n",
        "    which_behave = !which behave\n",
        "    if len(which_behave)==0:\n",
        "      %pip install behave\n",
        "      %pip install coverage\n",
        "    no_upper = 'a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v|via|vs'\n",
        "    title = ' '.join([x.capitalize() if x not in no_upper.split('|') else x for x in nb_to_test.split('_')]).replace('Bdd','BDD') \n",
        "    # title[0].capitalize()\n",
        "    # !behave\n",
        "    !coverage run --source=jai.nbpy.{get_module_name(nb_to_test)} -m behave #-q\n",
        "    !coverage html --title=\"{title}\" #{nb_to_test.replace('_',' ').title()}\"\n",
        "    !coverage json\n",
        "    return 'Ran tests for '+nb_to_test+' ('+module_name+') use shell command: coverage report'\n",
        "  return \"Running tests on tests causes infinite recursion.\"\n",
        "\n",
        "def view_coverage():\n",
        "  %run {c['nb_dir']}add_notebook_server.ipynb\n",
        "  #still no way to set media on stock pi/chromium\n",
        "  with open('htmlcov/style.css','r') as css:\n",
        "    ugh = css.read()\n",
        "    ugh = ugh.replace('dark','light')\n",
        "  with open('htmlcov/style.css','w') as css:\n",
        "    css.write(ugh)\n",
        "  %run_local_server\n",
        "\n",
        "# if c['nb_run_by']!=c['nb_name']:\n",
        "nb_convert_py(c['nb_name']) #so this file gets included =P\n",
        "# if nb_convert_bootstrap is True: \n",
        "nb_convert_py('bootstrap_a_notebook') #manual import means manual conversion"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 73
        },
        "id": "AZpOWlYmw7k-",
        "outputId": "13554600-7a79-4b41-af20-8a78fde5747c"
      },
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "'jai/nbpy/bootstrap.py'"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 15
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Testing"
      ],
      "metadata": {
        "id": "2zMxDY7Se_Zx"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# %run {c['nb_dir']}'encrypted_private_config.ipynb'\n",
        "# test_notebook('encrypted_private_config')\n",
        "# %%writefile features/steps/context.py\n",
        "# import os\n",
        "# import sys\n",
        "# sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../')))\n",
        "\n",
        "# import jai\n"
      ],
      "metadata": {
        "id": "cxdA-QQICWQI"
      },
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile features/{c.get('nb_name')}.feature\n",
        "Feature: test notebooks using bdd\n",
        "\n",
        "  Scenario: this notebook is named bdd_testing_a_notebook\n",
        "    Given we have imported \"jai.nbpy.bddtesting\"\n",
        "    When we get configuration key \"nb_name\"\n",
        "    Then configuration key \"nb_name\" is \"bdd_testing_a_notebook\"\n",
        "\n",
        "  Scenario: tests calling tests avoids infinite recursion\n",
        "    Given we have imported \"jai.nbpy.bddtesting\"\n",
        "    And we have imported \"jai.nbpy.bootstrap\"\n",
        "    When we run test_notebook on \"bootstrap_a_notebook\"\n",
        "    Then we see \"infinite recursion\" in output"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "PsxzVGNdRgcm",
        "outputId": "f3c802a8-c13d-4eb4-e916-698f8d2ebbe8"
      },
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing features/bdd_testing_a_notebook.feature\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "%%writefile features/steps/{c.get('nb_name')}.py\n",
        "from behave import *\n",
        "import os\n",
        "from importlib import import_module\n",
        "import jai\n",
        "\n",
        "\n",
        "@given(u'we have imported \"{nb_name_lower}\"')\n",
        "def step_impl(context, nb_name_lower):\n",
        "  try:\n",
        "    len(context.loaded_modules)\n",
        "  except:\n",
        "    context.loaded_modules = {}\n",
        "  \n",
        "  print('importing '+nb_name_lower)\n",
        "  context.loaded_modules[nb_name_lower] = import_module(nb_name_lower)\n",
        "  context.c=context.loaded_modules[nb_name_lower].c\n",
        "  print('loaded modules',context.loaded_modules)\n",
        "  print('context.c is',context.c)\n",
        "\n",
        "@given(u'we have imported the notebook for this step')\n",
        "def step_impl(context):\n",
        "  module_name = os.path.basename(__file__).replace('.py','') #this uses the *step* notebook name\n",
        "  print('module_name:',module_name)\n",
        "  imported_module = import_module(module_name)\n",
        "  context.c = imported_module.c\n",
        "\n",
        "@when(u'we get configuration key \"{key_name}\"')\n",
        "def step_impl(context, key_name):\n",
        "  val = context.c.get(key_name,None)\n",
        "  assert val is not None\n",
        "\n",
        "@then(u'configuration key \"{key_name}\" is \"{val}\"')\n",
        "def step_impl(context, key_name, val):\n",
        "  assert context.c[key_name]==val\n",
        "\n",
        "# @then(u'we will see \"{to_match}\" in the output')\n",
        "# def step_impl(context, to_match):\n",
        "#   assert to_match in context.output == True\n",
        "\n",
        "@then(u'we see \"{to_match}\" in output')\n",
        "def step_impl(context, to_match):\n",
        "  #os.system('coverage')\n",
        "  # output = os.popen('coverage report').read()\n",
        "  # print('coverage report:',output)\n",
        "  assert to_match in context.output\n",
        "\n",
        "@then(u'\"{var1}\" equals \"{var2}\"')\n",
        "def step_impl(context, var1, var2):\n",
        "  print('c3 is',context.c)\n",
        "  assert context.c[var1]==var2\n",
        "  assert context.failed is False\n",
        "\n",
        "@when(u'we run test_notebook on \"{function_arg}\"')\n",
        "def step_impl(context, function_arg):\n",
        "    import sys\n",
        "    #print('modules',sys.modules.keys())\n",
        "    from jai.nbpy.bddtesting import test_notebook\n",
        "    print('jainbpy!',test_notebook)\n",
        "    #context.output = context.loaded_modules['jai.nbpy.bddtesting'].test_notebook(function_arg) \n",
        "    context.output = test_notebook(function_arg)\n",
        "    print('context.output:',context.output)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "SMEaz7GRa_Vk",
        "outputId": "1c12eda3-c173-4dc7-eb13-77d3d2a3f4ae"
      },
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Writing features/steps/bdd_testing_a_notebook.py\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "if c['nb_name'] == c['nb_run_by'] and \"ipykernel_launcher\" in sys.argv[0]: \n",
        "  test_notebook(c['nb_name'])\n",
        "  view_coverage()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "resources": {
            "https://localhost:8000/": {
              "data": "PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvc3RyaWN0LmR0ZCI+CjxodG1sPgo8aGVhZD4KPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiPgo8dGl0bGU+RGlyZWN0b3J5IGxpc3RpbmcgZm9yIC88L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8aDE+RGlyZWN0b3J5IGxpc3RpbmcgZm9yIC88L2gxPgo8aHI+Cjx1bD4KPGxpPjxhIGhyZWY9Ii5jb25maWcvIj4uY29uZmlnLzwvYT48L2xpPgo8bGk+PGEgaHJlZj0iLmNvdmVyYWdlIj4uY292ZXJhZ2U8L2E+PC9saT4KPGxpPjxhIGhyZWY9ImNvdmVyYWdlLmpzb24iPmNvdmVyYWdlLmpzb248L2E+PC9saT4KPGxpPjxhIGhyZWY9ImRyaXZlLyI+ZHJpdmUvPC9hPjwvbGk+CjxsaT48YSBocmVmPSJmZWF0dXJlcy8iPmZlYXR1cmVzLzwvYT48L2xpPgo8bGk+PGEgaHJlZj0iaHRtbGNvdi8iPmh0bWxjb3YvPC9hPjwvbGk+CjxsaT48YSBocmVmPSJqYWkvIj5qYWkvPC9hPjwvbGk+CjxsaT48YSBocmVmPSJzYW1wbGVfZGF0YS8iPnNhbXBsZV9kYXRhLzwvYT48L2xpPgo8L3VsPgo8aHI+CjwvYm9keT4KPC9odG1sPgo=",
              "ok": true,
              "headers": [
                [
                  "content-type",
                  "text/html; charset=utf-8"
                ]
              ],
              "status": 200,
              "status_text": ""
            },
            "https://localhost:8000/htmlcov/": {
              "data": "[encoded data, 5208 characters]",
              "ok": true,
              "headers": [
                [
                  "content-type",
                  "text/html"
                ]
              ],
              "status": 200,
              "status_text": ""
            },
            "https://localhost:8000/htmlcov/style.css": {
              "data": "[encoded data, 16636 characters]",
              "ok": true,
              "headers": [
                [
                  "content-type",
                  "text/css"
                ]
              ],
              "status": 200,
              "status_text": ""
            },
            "https://localhost:8000/htmlcov/keybd_closed.png": {
              "data": "[encoded data, 12008 characters]",
              "ok": true,
              "headers": [
                [
                  "content-type",
                  "image/png"
                ]
              ],
              "status": 200,
              "status_text": ""
            },
            "https://localhost:8000/htmlcov/coverage_html.js": {
              "data": "[encoded data, 27536 characters]",
              "ok": true,
              "headers": [
                [
                  "content-type",
                  "application/javascript"
                ]
              ],
              "status": 200,
              "status_text": ""
            }
          },
          "height": 1000
        },
        "id": "ZWV9jD5k5o9w",
        "outputId": "92e4075a-e84c-4f7c-c87a-f95aa9e83ac7"
      },
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "test_notebook() bdd_testing_a_notebook run by bdd_testing_a_notebook self: /usr/local/lib/python3.8/dist-packages/ipykernel_launcher.py\n",
            "\n",
            "Feature: test notebooks using bdd\u001b[90m # features/bdd_testing_a_notebook.feature:1\u001b[0m\n",
            "\n",
            "  Scenario: this notebook is named bdd_testing_a_notebook \u001b[90m       # features/bdd_testing_a_notebook.feature:3\u001b[0m\n",
            "    \u001b[90mGiven \u001b[0m\u001b[90mwe have imported \"\u001b[0m\u001b[90m\u001b[1mjai.nbpy.bddtesting\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m                 # features/steps/bdd_testing_a_notebook.py:7\u001b[0m\n",
            "[NbConvertApp] Converting notebook drive/MyDrive/Colab Notebooks/bdd_testing_a_notebook.ipynb to python\n",
            "[NbConvertApp] Writing 8200 bytes to jai/nbpy/bddtesting.py\n",
            "[NbConvertApp] Converting notebook drive/MyDrive/Colab Notebooks/bootstrap_a_notebook.ipynb to python\n",
            "[NbConvertApp] Writing 3269 bytes to jai/nbpy/bootstrap.py\n",
            "\u001b[2A    \u001b[32mGiven \u001b[0m\u001b[32mwe have imported \"\u001b[0m\u001b[32m\u001b[1mjai.nbpy.bddtesting\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m                 # features/steps/bdd_testing_a_notebook.py:7 2.745s\u001b[0m\n",
            "    \u001b[90mWhen \u001b[0m\u001b[90mwe get configuration key \"\u001b[0m\u001b[90m\u001b[1mnb_name\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m                      # features/steps/bdd_testing_a_notebook.py:27\u001b[0m\n",
            "\u001b[2A    \u001b[32mWhen \u001b[0m\u001b[32mwe get configuration key \"\u001b[0m\u001b[32m\u001b[1mnb_name\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m                      # features/steps/bdd_testing_a_notebook.py:27 0.000s\u001b[0m\n",
            "    \u001b[90mThen \u001b[0m\u001b[90mconfiguration key \"\u001b[0m\u001b[90m\u001b[1mnb_name\u001b[0m\u001b[90m\" is \"\u001b[0m\u001b[90m\u001b[1mbdd_testing_a_notebook\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m # features/steps/bdd_testing_a_notebook.py:32\u001b[0m\n",
            "\u001b[2A    \u001b[32mThen \u001b[0m\u001b[32mconfiguration key \"\u001b[0m\u001b[32m\u001b[1mnb_name\u001b[0m\u001b[32m\" is \"\u001b[0m\u001b[32m\u001b[1mbdd_testing_a_notebook\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m # features/steps/bdd_testing_a_notebook.py:32 0.000s\u001b[0m\n",
            "\n",
            "  Scenario: tests calling tests avoids infinite recursion \u001b[90m # features/bdd_testing_a_notebook.feature:8\u001b[0m\n",
            "    \u001b[90mGiven \u001b[0m\u001b[90mwe have imported \"\u001b[0m\u001b[90m\u001b[1mjai.nbpy.bddtesting\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m           # features/steps/bdd_testing_a_notebook.py:7\u001b[0m\n",
            "\u001b[2A    \u001b[32mGiven \u001b[0m\u001b[32mwe have imported \"\u001b[0m\u001b[32m\u001b[1mjai.nbpy.bddtesting\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m           # features/steps/bdd_testing_a_notebook.py:7 0.000s\u001b[0m\n",
            "    \u001b[90mAnd \u001b[0m\u001b[90mwe have imported \"\u001b[0m\u001b[90m\u001b[1mjai.nbpy.bootstrap\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m              # features/steps/bdd_testing_a_notebook.py:7\u001b[0m\n",
            "\u001b[2A    \u001b[32mAnd \u001b[0m\u001b[32mwe have imported \"\u001b[0m\u001b[32m\u001b[1mjai.nbpy.bootstrap\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m              # features/steps/bdd_testing_a_notebook.py:7 0.020s\u001b[0m\n",
            "    \u001b[90mWhen \u001b[0m\u001b[90mwe run test_notebook on \"\u001b[0m\u001b[90m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m    # features/steps/bdd_testing_a_notebook.py:53\u001b[0m\n",
            "[NbConvertApp] Converting notebook drive/MyDrive/Colab Notebooks/bootstrap_a_notebook.ipynb to python\n",
            "[NbConvertApp] Writing 3269 bytes to jai/nbpy/bootstrap.py\n",
            "\u001b[2A    \u001b[32mWhen \u001b[0m\u001b[32mwe run test_notebook on \"\u001b[0m\u001b[32m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m    # features/steps/bdd_testing_a_notebook.py:53 1.117s\u001b[0m\n",
            "    \u001b[90mThen \u001b[0m\u001b[90mwe see \"\u001b[0m\u001b[90m\u001b[1minfinite recursion\u001b[0m\u001b[90m\" in output\u001b[0m\u001b[90m             # features/steps/bdd_testing_a_notebook.py:40\u001b[0m\n",
            "\u001b[2A    \u001b[32mThen \u001b[0m\u001b[32mwe see \"\u001b[0m\u001b[32m\u001b[1minfinite recursion\u001b[0m\u001b[32m\" in output\u001b[0m\u001b[90m             # features/steps/bdd_testing_a_notebook.py:40 0.000s\u001b[0m\n",
            "\n",
            "Feature: bootstrap a notebook\u001b[90m # features/bootstrap_a_notebook.feature:1\u001b[0m\n",
            "\n",
            "  Scenario: notebooks have names \u001b[90m                              # features/bootstrap_a_notebook.feature:7\u001b[0m\n",
            "    \u001b[90mGiven \u001b[0m\u001b[90mwe have imported \"\u001b[0m\u001b[90m\u001b[1mjai.nbpy.bootstrap\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m                # features/steps/bdd_testing_a_notebook.py:7\u001b[0m\n",
            "\u001b[2A    \u001b[32mGiven \u001b[0m\u001b[32mwe have imported \"\u001b[0m\u001b[32m\u001b[1mjai.nbpy.bootstrap\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m                # features/steps/bdd_testing_a_notebook.py:7 0.000s\u001b[0m\n",
            "    \u001b[90mWhen \u001b[0m\u001b[90mwe get configuration key \"\u001b[0m\u001b[90m\u001b[1mnb_name\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m                    # features/steps/bdd_testing_a_notebook.py:27\u001b[0m\n",
            "\u001b[2A    \u001b[32mWhen \u001b[0m\u001b[32mwe get configuration key \"\u001b[0m\u001b[32m\u001b[1mnb_name\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m                    # features/steps/bdd_testing_a_notebook.py:27 0.000s\u001b[0m\n",
            "    \u001b[90mThen \u001b[0m\u001b[90mconfiguration key \"\u001b[0m\u001b[90m\u001b[1mnb_name\u001b[0m\u001b[90m\" is \"\u001b[0m\u001b[90m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[90m\"\u001b[0m\u001b[90m # features/steps/bdd_testing_a_notebook.py:32\u001b[0m\n",
            "\u001b[2A    \u001b[32mThen \u001b[0m\u001b[32mconfiguration key \"\u001b[0m\u001b[32m\u001b[1mnb_name\u001b[0m\u001b[32m\" is \"\u001b[0m\u001b[32m\u001b[1mbootstrap_a_notebook\u001b[0m\u001b[32m\"\u001b[0m\u001b[90m # features/steps/bdd_testing_a_notebook.py:32 0.000s\u001b[0m\n",
            "\n",
            "2 features passed, 0 failed, 0 skipped\n",
            "3 scenarios passed, 0 failed, 0 skipped\n",
            "10 steps passed, 0 failed, 0 skipped, 0 undefined\n",
            "Took 0m3.883s\n",
            "Wrote HTML report to htmlcov/index.html\n",
            "Wrote JSON report to coverage.json\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Javascript object>"
            ],
            "application/javascript": [
              "\n",
              "        (async () => {\n",
              "            const url = new URL(await google.colab.kernel.proxyPort(8000, {'cache': true}));\n",
              "            const iframe = document.createElement('iframe');\n",
              "            iframe.src = url;\n",
              "            iframe.setAttribute('width', '100%');\n",
              "            iframe.setAttribute('height', '400');\n",
              "            iframe.setAttribute('frameborder', 0);\n",
              "            document.body.appendChild(iframe);\n",
              "        })();\n",
              "    "
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Now serving Jai at: https://l7b75bszrmi-496ff2e9c6d22116-8000-colab.googleusercontent.com/\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "print(c['nb_name'])"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "JkSM2t421L9j",
        "outputId": "19b08fca-1d3d-4f29-d243-3785fd459630"
      },
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "bdd_testing_a_notebook\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# EOF"
      ],
      "metadata": {
        "id": "GHuJKu92fML-"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "c['nb_name'] = c['nb_run_by'] # return name to calling script, if any"
      ],
      "metadata": {
        "id": "1mkPqsRse0z0"
      },
      "execution_count": 12,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "print(c['nb_name'])"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "9f8d5d9e-a700-496c-f3d0-4e8f2d027ada",
        "id": "ycMQOAIjXgtZ"
      },
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "bdd_testing_a_notebook\n"
          ]
        }
      ]
    }
  ]
}