From cf3bb72176a9da9abdce50040cbdc8e4b010207a Mon Sep 17 00:00:00 2001 From: Gordon Ball Date: Thu, 4 Feb 2016 20:17:20 +0100 Subject: [PATCH 1/3] Add a loader for declarative kernel tests in YAML --- ipython3.yaml | 24 +++++++++++++++++ test_kernels.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 ipython3.yaml create mode 100644 test_kernels.py diff --git a/ipython3.yaml b/ipython3.yaml new file mode 100644 index 0000000..f87c347 --- /dev/null +++ b/ipython3.yaml @@ -0,0 +1,24 @@ +kernel_name: python3 +language_name: python +code_hello_world: "print('hello, world')" +completion_samples: + - text: zi + matches: + - zip +complete_code_samples: + - "1" + - "print('hello, world')" + - "def f(x):\n return x*2\n\n" +incomplete_code_samples: + - "print('''hello" + - "def f(x):\n x*2" +code_page_something: zip? +code_generate_error: raise +code_execute_result: + - code: 1+1 + result: "2" +code_display_data: + - code: "from IPython.display import HTML, display; display(HTML('test'))" + mime: text/html + - code: "from IPython.display import Math, display; display(Math('\\frac{1}{2}'))" + mime: text/latex diff --git a/test_kernels.py b/test_kernels.py new file mode 100644 index 0000000..2ed9c90 --- /dev/null +++ b/test_kernels.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 + +""" +This reads multiple kernel test cases from YAML file(s), generates the unittest +objects for each, and then runs the unittest(s). + +The yaml file is expected to contain one or more documents like, which +correspond to the equivalent named fields in KernelTest + + kernel_name: foo + language_name: bar + code_hello_world: print + completion_samples: + - text: foo + matches: + - fooo + - foooo + - text: bar + matches: + - barrr + complete_code_samples: + - foo + - bar + incomplete_code_samples: + - foo + - bar + invalid_code_samples: + - foo + - bar + code_page_something: foo +""" + +import yaml +import unittest +import jupyter_kernel_test as jkt +import argparse +import os + +def load_specs(specfile): + """ + Load a YAML file, and convert each of the documents within into a + KernelTests subclass. Returns a list of class objects. + """ + test_classes = [] + assert os.path.exists(specfile) + with open(specfile) as sf: + for spec in yaml.load_all(sf): + assert isinstance(spec, dict) + assert 'kernel_name' in spec + tc = type(spec['kernel_name'], (jkt.KernelTests, ), spec) + test_classes.append(tc) + return test_classes + +def generate_test_suite(testclasses): + "Generate a TestSuite class from a list of unittest classes." + tests = [] + for testclass in testclasses: + tests.append(unittest.TestLoader().loadTestsFromTestCase(testclass)) + return unittest.TestSuite(tests) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("specfiles", nargs="+", + help="YAML files containing test specs") + parser.add_argument("-v", "--verbosity", default=2, type=int, + help="unittest verbosity") + opts = parser.parse_args() + + for f in opts.specfiles: + suite = generate_test_suite(load_specs(f)) + unittest.TextTestRunner(verbosity=opts.verbosity).run(suite) From 09a729389d9bc0680ab1873c78122807dbb8be89 Mon Sep 17 00:00:00 2001 From: Gordon Ball Date: Thu, 4 Feb 2016 20:22:01 +0100 Subject: [PATCH 2/3] Add a note in README --- README.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.rst b/README.rst index f7997ab..1b3f239 100644 --- a/README.rst +++ b/README.rst @@ -64,3 +64,7 @@ Use it like this: Run this file directly using python, or use nosetests/py.test to find and run it. + +You can also avoid the unittest boilerplate by writing the necessary code +samples in a YAML file, which can then be run with the ``test_kernels.py`` +script. From 73f059af2dc5a16b71b52a6a9194c5a229f95580 Mon Sep 17 00:00:00 2001 From: Gordon Ball Date: Sun, 7 Feb 2016 15:56:24 +0100 Subject: [PATCH 3/3] Add TOML example for comparison --- ipython3.toml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 ipython3.toml diff --git a/ipython3.toml b/ipython3.toml new file mode 100644 index 0000000..d0f7c6e --- /dev/null +++ b/ipython3.toml @@ -0,0 +1,33 @@ +kernel_name = "python3" +language_name = "python" + +code_hello_world = "print('hello, world')" + +complete_code_samples = [ + "1", + "print('hello, world')", + "def f(x):\n return x*2\n\n" +] + +incomplete_code_samples = [ + "print('''hello", + "def f(x):\n x*2" +] + +code_page_something = "zip?" +code_generate_error = "raise" + +[[completion_samples]] +text = "zi" +matches = ["zip"] + +[[code_execute_result]] +code = "1+1" +result = "2" + +[[code_display_data]] +code = "from IPython.display import HTML, display; display(HTML('test'))" +mime = "text/html" +[[code_display_data]] +code = "from IPython.display import Math, display; display(Math('\\frac{1}{2}'))" +mime = "text/latex"