12da489cd246702bee5938545b18a6f710ed214bcJamie Gennis#!/usr/bin/env python
22da489cd246702bee5938545b18a6f710ed214bcJamie Gennis#
32da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# Copyright 2012, Google Inc.
42da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# All rights reserved.
52da489cd246702bee5938545b18a6f710ed214bcJamie Gennis#
62da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# Redistribution and use in source and binary forms, with or without
72da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# modification, are permitted provided that the following conditions are
82da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# met:
92da489cd246702bee5938545b18a6f710ed214bcJamie Gennis#
102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis#     * Redistributions of source code must retain the above copyright
112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# notice, this list of conditions and the following disclaimer.
122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis#     * Redistributions in binary form must reproduce the above
132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# copyright notice, this list of conditions and the following disclaimer
142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# in the documentation and/or other materials provided with the
152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# distribution.
162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis#     * Neither the name of Google Inc. nor the names of its
172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# contributors may be used to endorse or promote products derived from
182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# this software without specific prior written permission.
192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis#
202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis"""Tests for handshake module."""
342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
362da489cd246702bee5938545b18a6f710ed214bcJamie Gennisimport unittest
372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
382da489cd246702bee5938545b18a6f710ed214bcJamie Gennisimport set_sys_path  # Update sys.path to locate mod_pywebsocket module.
392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
402da489cd246702bee5938545b18a6f710ed214bcJamie Gennisfrom mod_pywebsocket.common import ExtensionParameter
412da489cd246702bee5938545b18a6f710ed214bcJamie Gennisfrom mod_pywebsocket.common import ExtensionParsingException
422da489cd246702bee5938545b18a6f710ed214bcJamie Gennisfrom mod_pywebsocket.common import format_extensions
432da489cd246702bee5938545b18a6f710ed214bcJamie Gennisfrom mod_pywebsocket.common import parse_extensions
442da489cd246702bee5938545b18a6f710ed214bcJamie Gennisfrom mod_pywebsocket.handshake._base import HandshakeException
452da489cd246702bee5938545b18a6f710ed214bcJamie Gennisfrom mod_pywebsocket.handshake._base import validate_subprotocol
462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
482da489cd246702bee5938545b18a6f710ed214bcJamie Gennisclass HandshakerTest(unittest.TestCase):
492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    """A unittest for handshake module."""
502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    def test_validate_subprotocol(self):
522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        # should succeed.
532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        validate_subprotocol('sample', hixie=True)
542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        validate_subprotocol('Sample', hixie=True)
552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        validate_subprotocol('sample\x7eprotocol', hixie=True)
562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        validate_subprotocol('sample\x20protocol', hixie=True)
572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        validate_subprotocol('sample', hixie=False)
582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        validate_subprotocol('Sample', hixie=False)
592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        validate_subprotocol('sample\x7eprotocol', hixie=False)
602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        # should fail.
622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertRaises(HandshakeException,
632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          validate_subprotocol,
642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          '',
652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          hixie=True)
662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertRaises(HandshakeException,
672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          validate_subprotocol,
682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          'sample\x19protocol',
692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          hixie=True)
702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertRaises(HandshakeException,
712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          validate_subprotocol,
722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          'sample\x7fprotocol',
732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          hixie=True)
742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertRaises(HandshakeException,
752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          validate_subprotocol,
762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          # "Japan" in Japanese
772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          u'\u65e5\u672c',
782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          hixie=True)
792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertRaises(HandshakeException,
802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          validate_subprotocol,
812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          '',
822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          hixie=False)
832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertRaises(HandshakeException,
842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          validate_subprotocol,
852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          'sample\x09protocol',
862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          hixie=False)
872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertRaises(HandshakeException,
882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          validate_subprotocol,
892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          'sample\x19protocol',
902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          hixie=False)
912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertRaises(HandshakeException,
922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          validate_subprotocol,
932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          'sample\x20protocol',
942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          hixie=False)
952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertRaises(HandshakeException,
962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          validate_subprotocol,
972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          'sample\x7fprotocol',
982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          hixie=False)
992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertRaises(HandshakeException,
1002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          validate_subprotocol,
1012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          # "Japan" in Japanese
1022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          u'\u65e5\u672c',
1032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                          hixie=False)
1042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis_TEST_TOKEN_EXTENSION_DATA = [
1072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo', [('foo', [])]),
1082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar', [('foo', [('bar', None)])]),
1092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar=baz', [('foo', [('bar', 'baz')])]),
1102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar=baz; car=cdr', [('foo', [('bar', 'baz'), ('car', 'cdr')])]),
1112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar=baz, car; cdr',
1122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     [('foo', [('bar', 'baz')]), ('car', [('cdr', None)])]),
1132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('a, b, c, d',
1142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     [('a', []), ('b', []), ('c', []), ('d', [])]),
1152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ]
1162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis_TEST_QUOTED_EXTENSION_DATA = [
1192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar=""', [('foo', [('bar', '')])]),
1202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar=" baz "', [('foo', [('bar', ' baz ')])]),
1212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar=",baz;"', [('foo', [('bar', ',baz;')])]),
1222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar="\\\r\\\nbaz"', [('foo', [('bar', '\r\nbaz')])]),
1232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar="\\"baz"', [('foo', [('bar', '"baz')])]),
1242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar="\xbbbaz"', [('foo', [('bar', '\xbbbaz')])]),
1252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ]
1262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis_TEST_REDUNDANT_TOKEN_EXTENSION_DATA = [
1292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo \t ', [('foo', [])]),
1302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; \r\n bar', [('foo', [('bar', None)])]),
1312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar=\r\n \r\n baz', [('foo', [('bar', 'baz')])]),
1322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo ;bar = baz ', [('foo', [('bar', 'baz')])]),
1332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo,bar,,baz', [('foo', []), ('bar', []), ('baz', [])]),
1342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ]
1352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis_TEST_REDUNDANT_QUOTED_EXTENSION_DATA = [
1382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ('foo; bar="\r\n \r\n baz"', [('foo', [('bar', '  baz')])]),
1392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    ]
1402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1422da489cd246702bee5938545b18a6f710ed214bcJamie Gennisclass ExtensionsParserTest(unittest.TestCase):
1432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    def _verify_extension_list(self, expected_list, actual_list):
1452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        """Verifies that ExtensionParameter objects in actual_list have the
1462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        same members as extension definitions in expected_list. Extension
1472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        definition used in this test is a pair of an extension name and a
1482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        parameter dictionary.
1492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        """
1502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        self.assertEqual(len(expected_list), len(actual_list))
1522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for expected, actual in zip(expected_list, actual_list):
1532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            (name, parameters) = expected
1542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self.assertEqual(name, actual._name)
1552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self.assertEqual(parameters, actual._parameters)
1562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    def test_parse(self):
1582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for formatted_string, definition in _TEST_TOKEN_EXTENSION_DATA:
1592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self._verify_extension_list(
1602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                definition, parse_extensions(formatted_string,
1612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                             allow_quoted_string=False))
1622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for formatted_string, unused_definition in _TEST_QUOTED_EXTENSION_DATA:
1642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self.assertRaises(
1652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                ExtensionParsingException, parse_extensions,
1662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                formatted_string, False)
1672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    def test_parse_with_allow_quoted_string(self):
1692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for formatted_string, definition in _TEST_TOKEN_EXTENSION_DATA:
1702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self._verify_extension_list(
1712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                definition, parse_extensions(formatted_string,
1722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                             allow_quoted_string=True))
1732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for formatted_string, definition in _TEST_QUOTED_EXTENSION_DATA:
1752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self._verify_extension_list(
1762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                definition, parse_extensions(formatted_string,
1772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                             allow_quoted_string=True))
1782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    def test_parse_redundant_data(self):
1802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for (formatted_string,
1812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis             definition) in _TEST_REDUNDANT_TOKEN_EXTENSION_DATA:
1822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self._verify_extension_list(
1832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                definition, parse_extensions(formatted_string,
1842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                             allow_quoted_string=False))
1852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for (formatted_string,
1872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis             definition) in _TEST_REDUNDANT_QUOTED_EXTENSION_DATA:
1882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self.assertRaises(
1892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                ExtensionParsingException, parse_extensions,
1902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                formatted_string, False)
1912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    def test_parse_redundant_data_with_allow_quoted_string(self):
1932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for (formatted_string,
1942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis             definition) in _TEST_REDUNDANT_TOKEN_EXTENSION_DATA:
1952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self._verify_extension_list(
1962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                definition, parse_extensions(formatted_string,
1972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                             allow_quoted_string=True))
1982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for (formatted_string,
2002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis             definition) in _TEST_REDUNDANT_QUOTED_EXTENSION_DATA:
2012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self._verify_extension_list(
2022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                definition, parse_extensions(formatted_string,
2032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                             allow_quoted_string=True))
2042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    def test_parse_bad_data(self):
2062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        _TEST_BAD_EXTENSION_DATA = [
2072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ('foo; ; '),
2082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ('foo; a a'),
2092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ('foo foo'),
2102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            (',,,'),
2112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ('foo; bar='),
2122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ('foo; bar="hoge'),
2132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ('foo; bar="a\r"'),
2142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ('foo; bar="\\\xff"'),
2152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ('foo; bar=\ra'),
2162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ]
2172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for formatted_string in _TEST_BAD_EXTENSION_DATA:
2192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self.assertRaises(
2202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                ExtensionParsingException, parse_extensions, formatted_string)
2212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2232da489cd246702bee5938545b18a6f710ed214bcJamie Gennisclass FormatExtensionsTest(unittest.TestCase):
2242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    def test_format_extensions(self):
2262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for formatted_string, definitions in _TEST_TOKEN_EXTENSION_DATA:
2272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            extensions = []
2282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            for definition in definitions:
2292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                (name, parameters) = definition
2302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                extension = ExtensionParameter(name)
2312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                extension._parameters = parameters
2322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                extensions.append(extension)
2332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            self.assertEqual(
2342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                formatted_string, format_extensions(extensions))
2352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2372da489cd246702bee5938545b18a6f710ed214bcJamie Gennisif __name__ == '__main__':
2382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    unittest.main()
2392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# vi:sts=4 sw=4 et
242