Skip to content

Commit

Permalink
Merge pull request #122 from parente/numpydoc-for-tests
Browse files Browse the repository at this point in the history
Docstrings for all tests
  • Loading branch information
Carreau committed Mar 8, 2016
2 parents cf2cdd3 + f787cb9 commit 1811010
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 201 deletions.
1 change: 1 addition & 0 deletions kernel_gateway/tests/services/activity/test_activity.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
"""Tests for tracking client/kernel activities."""

import unittest
from kernel_gateway.services.activity.manager import ActivityManager, LAST_MESSAGE_TO_CLIENT, LAST_MESSAGE_TO_KERNEL, LAST_TIME_STATE_CHANGED, BUSY, CONNECTIONS, LAST_CLIENT_CONNECT, LAST_CLIENT_DISCONNECT
Expand Down
72 changes: 37 additions & 35 deletions kernel_gateway/tests/services/cell/test_parser.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
"""Tests for notebook cell parsing."""

from kernel_gateway.services.cell.parser import *
import unittest
import re
class TestAPICellParserUtils(unittest.TestCase):
import sys
from kernel_gateway.services.cell.parser import APICellParser

class TestAPICellParser(unittest.TestCase):
"""Unit tests the APICellParser class."""
def _test_parser_with_kernel_spec(self, kernel_spec, expected_comment):
"""Instantiates the parser using the given `kernel_spec` and asserts
whether it created the correct regular expression for the kernel
language comment syntax.
Parameters
----------
kernel_spec : str
Kernel spec name
expected_comment : str
Comment token in the kernel spec language
Raises
------
AssertionError
If the parser did not create the correct regex
"""
parser = APICellParser(kernel_spec)
self.assertEqual(
parser.kernelspec_api_indicator,
Expand All @@ -16,42 +36,23 @@ def _test_parser_with_kernel_spec(self, kernel_spec, expected_comment):
)
)

def test_init_uses_correct_default_comment(self):
'''Tests if the parser correctly sets the comment regex for unknown kernels'''
def test_init(self):
"""Parser should pick the correct comment syntax."""
self._test_parser_with_kernel_spec('some_unknown_kernel', '#')

def test_init_uses_correct_comment_for_spark_kernel(self):
'''Tests if the parser correctly sets the comment regex for spark kernel'''
self._test_parser_with_kernel_spec('scala', '//')

def test_init_uses_correct_comment_for_python2_kernel(self):
'''Tests if the parser correctly sets the comment regex for python2'''
self._test_parser_with_kernel_spec('python2', '#')

def test_init_uses_correct_comment_for_python3_kernel(self):
'''Tests if the parser correctly sets the comment regex for python3'''
self._test_parser_with_kernel_spec('python3', '#')

def test_init_uses_correct_comment_for_ir_kernel(self):
'''Tests if the parser correctly sets the comment regex for r'''
self._test_parser_with_kernel_spec('ir', '#')

def test_init_uses_correct_comment_for_julia_kernel(self):
'''Tests if the parser correctly sets the comment regex for julia'''
self._test_parser_with_kernel_spec('julia-0.3', '#')

def test_is_api_cell_is_true_for_api_cells(self):
'''Tests if the parser correctly identifies api cells'''
def test_is_api_cell(self):
"""Parser should correctly identify annotated API cells."""
parser = APICellParser('some_unknown_kernel')
self.assertTrue(parser.is_api_cell('# GET /yes'), 'API cell was not detected')

def test_is_api_cell_is_false_for_api_cells(self):
'''Tests if the parser correctly identifies non-api cells'''
parser = APICellParser('some_unknown_kernel')
self.assertFalse(parser.is_api_cell('no'), 'API cell was not detected')

def test_endpoints_are_sorted_default_strategy(self):
'''Tests if the parser correctly creates a list of endpoint, source tuples using the default sort strategy'''
def test_endpoint_sort_default_strategy(self):
"""Parser should sort duplicate endpoint paths."""
source_cells = [
'# POST /:foo',
'# POST /hello/:foo',
Expand All @@ -66,8 +67,10 @@ def test_endpoints_are_sorted_default_strategy(self):
endpoint, _ = endpoints[index]
self.assertEqual(expected_values[index], endpoint, 'Endpoint was not found in expected order')

def test_endpoints_are_sorted_default_strategy(self):
'''Tests if the parser correctly creates a list of endpoint, source tuples using a custom sort strategy'''
def test_endpoint_sort_custom_strategy(self):
"""Parser should sort duplicate endpoint paths using a custom sort
strategy.
"""
source_cells = [
'# POST /1',
'# POST /+',
Expand All @@ -92,7 +95,7 @@ def custom_sort_fun(endpoint):
self.assertEqual(expected_values[index], endpoint, 'Endpoint was not found in expected order')

def test_get_cell_endpoint_and_verb(self):
'''Tests the ability to extract API endpoint and verb from a cell'''
"""Parser should extract API endpoint and verb from cell annotations."""
parser = APICellParser('some_unknown_kernel')
endpoint, verb = parser.get_cell_endpoint_and_verb('# GET /foo')
self.assertEqual(endpoint, '/foo', 'Endpoint was not extracted correctly')
Expand All @@ -101,15 +104,12 @@ def test_get_cell_endpoint_and_verb(self):
self.assertEqual(endpoint, '/bar/quo', 'Endpoint was not extracted correctly')
self.assertEqual(verb, 'POST', 'Endpoint was not extracted correctly')

def test_get_cell_endpoint_and_verb_with_non_api_cell(self):
'''Tests the ability to extract API endpoint and verb from a cell when there is no API code'''
parser = APICellParser('some_unknown_kernel')
endpoint, verb = parser.get_cell_endpoint_and_verb('some regular code')
self.assertEqual(endpoint, None, 'Endpoint was not extracted correctly')
self.assertEqual(verb, None, 'Endpoint was not extracted correctly')

def test_endpoint_concatenation(self):
'''Multiple cells with the same URI and verb should concatenate.'''
"""Parser should concatenate multiple cells with the same verb+path."""
source_cells = [
'# POST /foo/:bar',
'# POST /foo/:bar',
Expand All @@ -129,7 +129,9 @@ def test_endpoint_concatenation(self):
self.assertEqual(endpoints['/foo/:bar']['GET'], '# GET /foo/:bar\n')

def test_endpoint_response_concatenation(self):
'''Multiple response cells with the same URI and verb should concatenate.'''
"""Parser should concatenate multiple response cells with the same
verb+path.
"""
source_cells = [
'# ResponseInfo POST /foo/:bar',
'# ResponseInfo POST /foo/:bar',
Expand Down
47 changes: 31 additions & 16 deletions kernel_gateway/tests/services/notebooks/test_request_utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
"""Tests for notebook request utilities."""

from kernel_gateway.services.notebooks.request_utils import *
import unittest, json
import unittest
import json
from kernel_gateway.services.notebooks.request_utils import (format_request,
parse_body, parameterize_path, headers_to_dict, parse_args)

class MockRequest(dict):
def __init__(self, *args, **kwargs):
Expand All @@ -17,7 +20,9 @@ def get_all(self):
return self.headers

class TestRequestUtils(unittest.TestCase):
"""Unit tests the request utility helper functions."""
def test_parse_body_text(self):
"""Should parse the body text from a byte stream to a string."""
request = MockRequest()
request.body = b'test value'
request.headers = {
Expand All @@ -27,6 +32,7 @@ def test_parse_body_text(self):
self.assertEqual(result, "test value", 'Did not properly parse text body.')

def test_parse_body_json(self):
"""Should parse the body from a JSON byte stream to a dict."""
request = MockRequest()
request.body = b'{ "foo" : "bar" }'
request.headers = {
Expand All @@ -36,6 +42,7 @@ def test_parse_body_json(self):
self.assertEqual(result, { 'foo' : 'bar' }, 'Did not properly parse json body.')

def test_parse_body_bad_json(self):
"""Should parse the body from an invalid JSON byte stream to a string."""
request = MockRequest()
request.body = b'{ "foo" "bar" }'
request.headers = {
Expand All @@ -44,8 +51,8 @@ def test_parse_body_bad_json(self):
result = parse_body(request)
self.assertEqual(result, '{ "foo" "bar" }', 'Did not properly parse json body.')


def test_parse_body_multipart_form(self):
"""Should parse body arguments from multipart form data to a dict."""
request = MockRequest()
request.body = None
request.body_arguments = { 'foo' : [b'bar']}
Expand All @@ -56,6 +63,7 @@ def test_parse_body_multipart_form(self):
self.assertEqual(result, { 'foo' : ['bar']}, 'Did not properly parse json body.')

def test_parse_body_url_encoded_form(self):
"""Should parse body arguments from urlencoded form data to a dict."""
request = MockRequest()
request.body = None
request.body_arguments = { 'foo' : [b'bar']}
Expand All @@ -66,20 +74,23 @@ def test_parse_body_url_encoded_form(self):
self.assertEqual(result, { 'foo' : ['bar']}, 'Did not properly parse json body.')

def test_parse_body_empty(self):
"""Should parse an empty body to an empty string."""
request = MockRequest()
request.body = b''
request.headers = {}
result = parse_body(request)
self.assertEqual(result, '', 'Did not properly handle body = empty string.')

def test_parse_body_defaults_to_text_plain(self):
"""Should parse a body to a string by default."""
request = MockRequest()
request.body = b'{"foo" : "bar"}'
request.headers = {}
result = parse_body(request)
self.assertEqual(result, '{"foo" : "bar"}', 'Did not properly handle body = empty string.')

def test_parse_args(self):
"""Should parse URL argument byte streams to strings."""
result = parse_args({'arga': [ b'1234', b'4566'], 'argb' : [b'hello']})
self.assertEqual(
result,
Expand All @@ -88,41 +99,45 @@ def test_parse_args(self):
)

def test_parameterize_path(self):
"""Should parse URLs with path parameters into regular expressions."""
result = parameterize_path('/foo/:bar')
self.assertEqual(result, '/foo/(?P<bar>[^\/]+)')
self.assertEqual(result, r'/foo/(?P<bar>[^\/]+)')
result = parameterize_path('/foo/:bar/baz/:quo')
self.assertEqual(result, '/foo/(?P<bar>[^\/]+)/baz/(?P<quo>[^\/]+)')
self.assertEqual(result, r'/foo/(?P<bar>[^\/]+)/baz/(?P<quo>[^\/]+)')

def test_whitespace_in_paths(self):
"""Should handle whitespace in the path."""
result = parameterize_path('/foo/:bar ')
self.assertEqual(result, '/foo/(?P<bar>[^\/]+)')
self.assertEqual(result, r'/foo/(?P<bar>[^\/]+)')
result = parameterize_path('/foo/:bar/baz ')
self.assertEqual(result, '/foo/(?P<bar>[^\/]+)/baz')
self.assertEqual(result, r'/foo/(?P<bar>[^\/]+)/baz')

def test_headers_to_dict(self):
"""Should parse headers into a dictionary."""
result = headers_to_dict(MockHeaders([('Content-Type', 'application/json'), ('Set-Cookie', 'A=B'), ('Set-Cookie', 'C=D')]))
self.assertEqual(result['Content-Type'], 'application/json','Single value for header was not assigned correctly')
self.assertEqual(result['Set-Cookie'], ['A=B','C=D'],'Single value for header was not assigned correctly')

def test_headers_to_dict_with_no_headers(self):
"""Should parse empty headers into an empty dictionary."""
result = headers_to_dict(MockHeaders([]))
self.assertEqual(result, {},'Empty headers handled incorrectly and did not make empty dict')

def test_format_request_code_not_escaped(self):
'''Test formatting request code without escaped quotes'''
test_request = ('{"body": "", "headers": {"Accept-Language": "en-US,en;q=0.8", '
'"If-None-Match": "9a28a9262f954494a8de7442c63d6d0715ce0998", '
'"Accept-Encoding": "gzip, deflate, sdch"}, "args": {}, "path": {}}')
def test_format_request_code_not_escaped(self):
"""Should handle quotes in headers."""
test_request = ('''{"body": "", "headers": {"Accept-Language": "en-US,en;q=0.8",
"If-None-Match": "9a28a9262f954494a8de7442c63d6d0715ce0998",
"Accept-Encoding": "gzip, deflate, sdch"}, "args": {}, "path": {}}''')
request_code = format_request(test_request)
#Get the value of REQUEST = "{ to test for equality
test_request_js_value = request_code[request_code.index("\"{"):]
self.assertEqual(test_request, json.loads(test_request_js_value), "Request code without escaped quotes was not formatted correctly")

def test_format_request_code_escaped(self):
'''Test formatting request code where multiple escaped quotes exist'''
test_request = ('{"body": "", "headers": {"Accept-Language": "en-US,en;q=0.8", '
'"If-None-Match": "\"\"9a28a9262f954494a8de7442c63d6d0715ce0998\"\"", '
'"Accept-Encoding": "gzip, deflate, sdch"}, "args": {}, "path": {}}')
"""Should handle backslash escaped characeters in headers."""
test_request = ('''{"body": "", "headers": {"Accept-Language": "en-US,en;q=0.8",
"If-None-Match": "\"\"9a28a9262f954494a8de7442c63d6d0715ce0998\"\"",
"Accept-Encoding": "gzip, deflate, sdch"}, "args": {}, "path": {}}''')
request_code = format_request(test_request)
#Get the value of REQUEST = "{ to test for equality
test_request_js_value = request_code[request_code.index("\"{"):]
Expand Down
11 changes: 7 additions & 4 deletions kernel_gateway/tests/services/swagger/test_builders.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
"""Tests for swagger spec generation."""

from kernel_gateway.services.swagger.builders import *
import unittest
from kernel_gateway.services.swagger.builders import SwaggerSpecBuilder

class TestSwaggerBuilders(unittest.TestCase):
"""Unit tests the swagger spec builder."""
def test_add_title_adds_title_to_spec(self):
'''When a title is set on the builder, it should be reflected in the result'''
"""Builder should store an API title."""
expected = 'Some New Title'
builder = SwaggerSpecBuilder('some_spec')
builder.set_title(expected)
result = builder.build()
self.assertEqual(result['info']['title'] ,expected,'Title was not set to new value')

def test_add_cell_adds_api_cell_to_spec(self):
'''When an api cell is added to the builder, it should be reflected in the result'''
"""Builder should store an API cell annotation."""
expected = {
'get' : {
'responses' : {
Expand All @@ -27,7 +30,7 @@ def test_add_cell_adds_api_cell_to_spec(self):
self.assertEqual(result['paths']['/some/resource'] ,expected,'Title was not set to new value')

def test_add_cell_does_not_add_non_api_cell_to_spec(self):
'''When a non-api cell is added to the builder, it should not be reflected in the result'''
"""Builder should store ignore non- API cells."""
builder = SwaggerSpecBuilder('some_spec')
builder.add_cell('regular code cell')
result = builder.build()
Expand Down
26 changes: 17 additions & 9 deletions kernel_gateway/tests/test_gatewayapp.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
"""Tests for basic gateway app behavior."""

import logging
import unittest
Expand All @@ -10,14 +11,17 @@
RESOURCES = os.path.join(os.path.dirname(__file__), 'resources')

class TestGatewayAppConfig(unittest.TestCase):
"""Tests configuration of the gateway app."""
def setUp(self):
"""Saves a copy of the environment."""
self.environ = dict(os.environ)

def tearDown(self):
"""Resets the environment."""
os.environ = self.environ

def test_config_env_vars(self):
'''Env vars should be honored for traitlets.'''
"""Env vars should be honored for traitlets."""
# Environment vars are always strings
os.environ['KG_PORT'] = '1234'
os.environ['KG_IP'] = '1.1.1.1'
Expand Down Expand Up @@ -56,21 +60,26 @@ def test_config_env_vars(self):
self.assertEqual(app.allow_notebook_download, True)

class TestGatewayAppBase(AsyncHTTPTestCase, LogTrapTestCase):
'''
Base class for integration style tests using HTTP/Websockets against an
"""Base class for integration style tests using HTTP/Websockets against an
instance of the gateway app..
'''
Attributes
----------
app : KernelGatewayApp
Instance of the app
"""
def tearDown(self):
"""Shuts down the app after test run."""
if self.app:
self.app.shutdown()
super(TestGatewayAppBase, self).tearDown()

def get_new_ioloop(self):
'''Use a global zmq ioloop for tests.'''
"""Uses a global zmq ioloop for tests."""
return ioloop.IOLoop.current()

def get_app(self):
'''Returns a tornado.web.Application for system tests.'''
"""Returns a tornado.web.Application for the Tornado test runner."""
if hasattr(self, '_app'):
return self._app
self.app = KernelGatewayApp(log_level=logging.CRITICAL)
Expand All @@ -80,8 +89,7 @@ def get_app(self):
return self.app.web_app

def setup_app(self):
'''
Override to configure KernelGatewayApp instance before initializing
"""Override to configure KernelGatewayApp instance before initializing
configurables and the web app.
'''
"""
pass

0 comments on commit 1811010

Please sign in to comment.