From 1de10b1b740ae84a51c6f4e52374afdbbc10d74c Mon Sep 17 00:00:00 2001 From: Dieter Verfaillie Date: Wed, 28 Nov 2012 19:48:47 +0100 Subject: giscanner: move unit tests from giscanner/annotationpatters.py... ... to tests/scanner/annotationparser/test_patterns.py because the following patch will remove giscanner/annotationpatters.py https://bugzilla.gnome.org/show_bug.cgi?id=688897 --- Makefile.am | 2 +- giscanner/annotationpatterns.py | 556 ---------------------- tests/scanner/annotationparser/README | 11 + tests/scanner/annotationparser/test_patterns.py | 590 ++++++++++++++++++++++++ 4 files changed, 602 insertions(+), 557 deletions(-) create mode 100644 tests/scanner/annotationparser/test_patterns.py diff --git a/Makefile.am b/Makefile.am index 76837554..c4f67031 100644 --- a/Makefile.am +++ b/Makefile.am @@ -65,7 +65,7 @@ check-local: @echo "TEST: PEP-8 INQUISITION" @find $(top_srcdir)/giscanner -name \*.py | sort | uniq | xargs $(PYTHON) $(top_srcdir)/misc/pep8.py --repeat --exclude=config.py @echo "TEST: Annotation pattern programs" - $(PYTHON) $(top_srcdir)/giscanner/annotationpatterns.py + PYTHONPATH="$(top_builddir):$(top_srcdir)" $(PYTHON) $(top_srcdir)/tests/scanner/annotationparser/test_patterns.py @echo "TEST: GTK-Doc Annotation Parser" PYTHONPATH="$(top_builddir):$(top_srcdir)" $(PYTHON) $(top_srcdir)/tests/scanner/annotationparser/test_parser.py @touch $(top_builddir)/.make-check-passed diff --git a/giscanner/annotationpatterns.py b/giscanner/annotationpatterns.py index a4030051..95c11c9e 100644 --- a/giscanner/annotationpatterns.py +++ b/giscanner/annotationpatterns.py @@ -250,559 +250,3 @@ MULTILINE_ANNOTATION_CONTINUATION_RE = re.compile(r''' $ # end ''', re.VERBOSE | re.MULTILINE) - - -if __name__ == '__main__': - import unittest - - identifier_section_tests = [ - (SECTION_RE, 'TSIEOCN', - None), - (SECTION_RE, 'section', - None), - (SECTION_RE, 'section:', - None), - (SECTION_RE, 'section:test', - None), - (SECTION_RE, 'SECTION', - {'colon': '', - 'section_name': None}), - (SECTION_RE, 'SECTION \t ', - {'colon': '', - 'section_name': None}), - (SECTION_RE, ' \t SECTION \t ', - {'colon': '', - 'section_name': None}), - (SECTION_RE, 'SECTION: \t ', - {'colon': ':', - 'section_name': None}), - (SECTION_RE, 'SECTION : ', - {'colon': ':', - 'section_name': None}), - (SECTION_RE, ' SECTION : ', - {'colon': ':', - 'section_name': None}), - (SECTION_RE, 'SECTION:gtkwidget', - {'colon': ':', - 'section_name': 'gtkwidget'}), - (SECTION_RE, 'SECTION:gtkwidget ', - {'colon': ':', - 'section_name': 'gtkwidget'}), - (SECTION_RE, ' SECTION:gtkwidget', - {'colon': ':', - 'section_name': 'gtkwidget'}), - (SECTION_RE, ' SECTION:gtkwidget\t ', - {'colon': ':', - 'section_name': 'gtkwidget'}), - (SECTION_RE, 'SECTION: gtkwidget ', - {'colon': ':', - 'section_name': 'gtkwidget'}), - (SECTION_RE, 'SECTION : gtkwidget', - {'colon': ':', - 'section_name': 'gtkwidget'}), - (SECTION_RE, 'SECTION gtkwidget \f ', - {'colon': '', - 'section_name': 'gtkwidget'})] - - identifier_symbol_tests = [ - (SYMBOL_RE, 'GBaseFinalizeFunc:', - {'colon': ':', - 'symbol_name': 'GBaseFinalizeFunc', - 'annotations': ''}), - (SYMBOL_RE, 'gtk_widget_show ', - {'colon': '', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, ' gtk_widget_show', - {'colon': '', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, ' gtk_widget_show ', - {'colon': '', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, 'gtk_widget_show:', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, 'gtk_widget_show :', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, 'gtk_widget_show: ', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, 'gtk_widget_show : ', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, ' gtk_widget_show:', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, ' gtk_widget_show :', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, ' gtk_widget_show: ', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, ' gtk_widget_show : ', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': ''}), - (SYMBOL_RE, 'gtk_widget_show (skip)', - {'colon': '', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip)'}), - (SYMBOL_RE, 'gtk_widget_show: (skip)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip)'}), - (SYMBOL_RE, 'gtk_widget_show : (skip)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip)'}), - (SYMBOL_RE, 'gtk_widget_show: (skip)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip)'}), - (SYMBOL_RE, 'gtk_widget_show : (skip)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip)'}), - (SYMBOL_RE, ' gtk_widget_show:(skip)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip)'}), - (SYMBOL_RE, ' gtk_widget_show :(skip)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip)'}), - (SYMBOL_RE, ' gtk_widget_show: (skip)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip)'}), - (SYMBOL_RE, ' gtk_widget_show : (skip) \t ', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) \t '}), - (SYMBOL_RE, ' gtk_widget_show : (skip) \t ', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) \t '}), - (SYMBOL_RE, 'gtk_widget_show:(skip)(test1)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip)(test1)'}), - (SYMBOL_RE, 'gtk_widget_show (skip)(test1)', - {'colon': '', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip)(test1)'}), - (SYMBOL_RE, 'gtk_widget_show: (skip) (test1)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1)'}), - (SYMBOL_RE, 'gtk_widget_show : (skip) (test1)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1)'}), - (SYMBOL_RE, 'gtk_widget_show: (skip) (test1)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1)'}), - (SYMBOL_RE, 'gtk_widget_show : (skip) (test1)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1)'}), - (SYMBOL_RE, ' gtk_widget_show:(skip) (test1)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1)'}), - (SYMBOL_RE, ' gtk_widget_show :(skip) (test1)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1)'}), - (SYMBOL_RE, ' gtk_widget_show: (skip) (test1)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1)'}), - (SYMBOL_RE, ' gtk_widget_show : (skip) (test1) ', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1) '}), - (SYMBOL_RE, 'gtk_widget_show: (skip) (test1) (test-2)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1) (test-2)'}), - (SYMBOL_RE, 'gtk_widget_show : (skip) (test1) (test-2)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1) (test-2)'}), - (SYMBOL_RE, 'gtk_widget_show: (skip) (test1) (test-2)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1) (test-2)'}), - (SYMBOL_RE, 'gtk_widget_show : (skip) (test1) (test-2)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1) (test-2)'}), - (SYMBOL_RE, ' gtk_widget_show:(skip) (test1) (test-2)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1) (test-2)'}), - (SYMBOL_RE, ' gtk_widget_show :(skip) (test1) (test-2)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1) (test-2)'}), - (SYMBOL_RE, ' gtk_widget_show: (skip) (test1) (test-2)', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1) (test-2)'}), - (SYMBOL_RE, ' gtk_widget_show : (skip) (test1) (test-2) ', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1) (test-2) '}), - (SYMBOL_RE, ' gtk_widget_show : (skip) (test1) (test-2) ', - {'colon': ':', - 'symbol_name': 'gtk_widget_show', - 'annotations': '(skip) (test1) (test-2) '}), - # constants - (SYMBOL_RE, 'MY_CONSTANT:', - {'colon': ':', - 'symbol_name': 'MY_CONSTANT', - 'annotations': ''}), - # structs - (SYMBOL_RE, 'FooWidget:', - {'colon': ':', - 'symbol_name': 'FooWidget', - 'annotations': ''}), - # enums - (SYMBOL_RE, 'Something:', - {'colon': ':', - 'symbol_name': 'Something', - 'annotations': ''})] - - identifier_property_tests = [ - # simple property name - (PROPERTY_RE, 'GtkWidget:name (skip)', - {'class_name': 'GtkWidget', - 'property_name': 'name', - 'colon': '', - 'annotations': '(skip)'}), - (PROPERTY_RE, 'GtkWidget:name', - {'class_name': 'GtkWidget', - 'property_name': 'name', - 'colon': '', - 'annotations': ''}), - (PROPERTY_RE, ' GtkWidget :name', - {'class_name': 'GtkWidget', - 'property_name': 'name', - 'colon': '', - 'annotations': ''}), - (PROPERTY_RE, 'GtkWidget: name ', - {'class_name': 'GtkWidget', - 'property_name': 'name', - 'colon': '', - 'annotations': ''}), - (PROPERTY_RE, ' GtkWidget : name ', - {'class_name': 'GtkWidget', - 'property_name': 'name', - 'colon': '', - 'annotations': ''}), - (PROPERTY_RE, 'GtkWidget:name:', - {'class_name': 'GtkWidget', - 'property_name': 'name', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, 'GtkWidget:name: ', - {'class_name': 'GtkWidget', - 'property_name': 'name', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, ' GtkWidget:name:', - {'class_name': 'GtkWidget', - 'property_name': 'name', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, 'Something:name:', - {'class_name': 'Something', - 'property_name': 'name', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, 'Something:name: ', - {'class_name': 'Something', - 'property_name': 'name', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, ' Something:name:', - {'class_name': 'Something', - 'property_name': 'name', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, 'Weird-thing:name:', - None), - (PROPERTY_RE, 'really-weird_thing:name:', - None), - (PROPERTY_RE, 'GWin32InputStream:handle:', - {'class_name': 'GWin32InputStream', - 'property_name': 'handle', - 'colon': ':', - 'annotations': ''}), - # property name that contains a dash - (PROPERTY_RE, 'GtkWidget:double-buffered (skip)', - {'class_name': 'GtkWidget', - 'property_name': 'double-buffered', - 'colon': '', - 'annotations': '(skip)'}), - (PROPERTY_RE, 'GtkWidget:double-buffered', - {'class_name': 'GtkWidget', - 'property_name': 'double-buffered', - 'colon': '', - 'annotations': ''}), - (PROPERTY_RE, ' GtkWidget :double-buffered', - {'class_name': 'GtkWidget', - 'property_name': 'double-buffered', - 'colon': '', - 'annotations': ''}), - (PROPERTY_RE, 'GtkWidget: double-buffered ', - {'class_name': 'GtkWidget', - 'property_name': 'double-buffered', - 'colon': '', - 'annotations': ''}), - (PROPERTY_RE, ' GtkWidget : double-buffered ', - {'class_name': 'GtkWidget', - 'property_name': 'double-buffered', - 'colon': '', - 'annotations': ''}), - (PROPERTY_RE, 'GtkWidget:double-buffered:', - {'class_name': 'GtkWidget', - 'property_name': 'double-buffered', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, 'GtkWidget:double-buffered: ', - {'class_name': 'GtkWidget', - 'property_name': 'double-buffered', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, ' GtkWidget:double-buffered:', - {'class_name': 'GtkWidget', - 'property_name': 'double-buffered', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, 'Something:double-buffered:', - {'class_name': 'Something', - 'property_name': 'double-buffered', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, 'Something:double-buffered: ', - {'class_name': 'Something', - 'property_name': 'double-buffered', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, ' Something:double-buffered:', - {'class_name': 'Something', - 'property_name': 'double-buffered', - 'colon': ':', - 'annotations': ''}), - (PROPERTY_RE, 'Weird-thing:double-buffered:', - None), - (PROPERTY_RE, 'really-weird_thing:double-buffered:', - None), - (PROPERTY_RE, ' GMemoryOutputStream:realloc-function: (skip)', - {'class_name': 'GMemoryOutputStream', - 'property_name': 'realloc-function', - 'colon': ':', - 'annotations': '(skip)'})] - - identifier_signal_tests = [ - # simple property name - (SIGNAL_RE, 'GtkWidget::changed: (skip)', - {'class_name': 'GtkWidget', - 'signal_name': 'changed', - 'colon': ':', - 'annotations': '(skip)'}), - (SIGNAL_RE, 'GtkWidget::changed:', - {'class_name': 'GtkWidget', - 'signal_name': 'changed', - 'colon': ':', - 'annotations': ''}), - (SIGNAL_RE, 'Something::changed:', - {'class_name': 'Something', - 'signal_name': 'changed', - 'colon': ':', - 'annotations': ''}), - (SIGNAL_RE, 'Weird-thing::changed:', - None), - (SIGNAL_RE, 'really-weird_thing::changed:', - None), - # property name that contains a dash - (SIGNAL_RE, 'GtkWidget::hierarchy-changed: (skip)', - {'class_name': 'GtkWidget', - 'signal_name': 'hierarchy-changed', - 'colon': ':', - 'annotations': '(skip)'}), - (SIGNAL_RE, 'GtkWidget::hierarchy-changed:', - {'class_name': 'GtkWidget', - 'signal_name': 'hierarchy-changed', - 'colon': ':', - 'annotations': ''}), - (SIGNAL_RE, 'Something::hierarchy-changed:', - {'class_name': 'Something', - 'signal_name': 'hierarchy-changed', - 'colon': ':', - 'annotations': ''}), - (SIGNAL_RE, 'Weird-thing::hierarchy-changed:', - None), - (SIGNAL_RE, 'really-weird_thing::hierarchy-changed:', - None)] - - parameter_tests = [ - (PARAMETER_RE, '@Short_description: Base class for all widgets ', - {'parameter_name': 'Short_description', - 'annotations': '', - 'colon': '', - 'description': 'Base class for all widgets'}), - (PARAMETER_RE, '@...: the value of the first property, followed optionally by more', - {'parameter_name': '...', - 'annotations': '', - 'colon': '', - 'description': 'the value of the first property, followed optionally by more'}), - (PARAMETER_RE, '@widget: a #GtkWidget', - {'parameter_name': 'widget', - 'annotations': '', - 'colon': '', - 'description': 'a #GtkWidget'}), - (PARAMETER_RE, '@widget_pointer: (inout) (transfer none): ' - 'address of a variable that contains @widget', - {'parameter_name': 'widget_pointer', - 'annotations': '(inout) (transfer none)', - 'colon': ':', - 'description': 'address of a variable that contains @widget'}), - (PARAMETER_RE, '@weird_thing: (inout) (transfer none) (allow-none) (attribute) (destroy) ' - '(foreign) (inout) (out) (transfer) (skip) (method): some weird @thing', - {'parameter_name': 'weird_thing', - 'annotations': '(inout) (transfer none) (allow-none) (attribute) (destroy) ' - '(foreign) (inout) (out) (transfer) (skip) (method)', - 'colon': ':', - 'description': 'some weird @thing'}), - (PARAMETER_RE, '@data: a pointer to the element data. The data may be moved as elements ' - 'are added to the #GByteArray.', - {'parameter_name': 'data', - 'annotations': '', - 'colon': '', - 'description': 'a pointer to the element data. The data may be moved as elements ' - 'are added to the #GByteArray.'}), - (PARAMETER_RE, '@a: a #GSequenceIter', - {'parameter_name': 'a', - 'annotations': '', - 'colon': '', - 'description': 'a #GSequenceIter'}), - (PARAMETER_RE, '@keys: (array length=n_keys) (element-type GQuark) (allow-none):', - {'parameter_name': 'keys', - 'annotations': '(array length=n_keys) (element-type GQuark) (allow-none)', - 'colon': ':', - 'description': ''})] - - tag_tests = [ - (TAG_RE, 'Since 3.0', - None), - (TAG_RE, 'Since: 3.0', - {'tag_name': 'Since', - 'annotations': '', - 'colon': '', - 'description': '3.0'}), - (TAG_RE, 'Attributes: (inout) (transfer none): some note about attributes', - {'tag_name': 'Attributes', - 'annotations': '(inout) (transfer none)', - 'colon': ':', - 'description': 'some note about attributes'}), - (TAG_RE, 'Rename to: something_else', - {'tag_name': 'Rename to', - 'annotations': '', - 'colon': '', - 'description': 'something_else'}), - (TAG_RE, '@Deprecated: Since 2.8, reference counting is done atomically', - None), - (TAG_RE, 'Returns %TRUE and does weird things', - None), - (TAG_RE, 'Returns: a #GtkWidget', - {'tag_name': 'Returns', - 'annotations': '', - 'colon': '', - 'description': 'a #GtkWidget'}), - (TAG_RE, 'Return value: (transfer none): The binary data that @text responds. ' - 'This pointer', - {'tag_name': 'Return value', - 'annotations': '(transfer none)', - 'colon': ':', - 'description': 'The binary data that @text responds. This pointer'}), - (TAG_RE, 'Return value: (transfer full) (array length=out_len) (element-type guint8):', - {'tag_name': 'Return value', - 'annotations': '(transfer full) (array length=out_len) (element-type guint8)', - 'colon': ':', - 'description': ''}), - (TAG_RE, 'Returns: A boolean value, but let me tell you a bit about this boolean. It', - {'tag_name': 'Returns', - 'annotations': '', - 'colon': '', - 'description': 'A boolean value, but let me tell you a bit about this boolean. ' - 'It'}), - (TAG_RE, 'Returns: (transfer container) (element-type GObject.ParamSpec): a', - {'tag_name': 'Returns', - 'annotations': '(transfer container) (element-type GObject.ParamSpec)', - 'colon': ':', - 'description': 'a'}), - (TAG_RE, 'Return value: (type GLib.HashTable>) ' - '(transfer full):', - {'tag_name': 'Return value', - 'annotations': '(type GLib.HashTable>) ' - '(transfer full)', - 'colon': ':', - 'description': ''})] - - - def create_tests(cls, test_name, testcases): - for (index, testcase) in enumerate(testcases): - real_test_name = '%s_%03d' % (test_name, index) - - test_method = cls.__create_test__(testcase) - test_method.__name__ = real_test_name - setattr(cls, real_test_name, test_method) - - - class TestProgram(unittest.TestCase): - @classmethod - def __create_test__(cls, testcase): - def do_test(self): - (program, text, expected) = testcase - - match = program.search(text) - - if expected is None: - msg = 'Program matched text but shouldn\'t:\n"%s"' - self.assertTrue(match is None, msg % (text)) - else: - msg = 'Program should match text but didn\'t:\n"%s"' - self.assertTrue(match is not None, msg % (text)) - - for key, value in expected.items(): - msg = 'expected "%s" for "%s" but match returned "%s"' - msg = msg % (value, key, match.group(key)) - self.assertEqual(match.group(key), value, msg) - - return do_test - - - # Create tests from data - create_tests(TestProgram, 'test_identifier_section', identifier_section_tests) - create_tests(TestProgram, 'test_identifier_symbol', identifier_symbol_tests) - create_tests(TestProgram, 'test_identifier_property', identifier_property_tests) - create_tests(TestProgram, 'test_identifier_signal', identifier_signal_tests) - create_tests(TestProgram, 'test_parameter', parameter_tests) - create_tests(TestProgram, 'test_tag', tag_tests) - - # Run test suite - unittest.main() diff --git a/tests/scanner/annotationparser/README b/tests/scanner/annotationparser/README index 1f621a57..03cdf59d 100644 --- a/tests/scanner/annotationparser/README +++ b/tests/scanner/annotationparser/README @@ -1,3 +1,14 @@ +test_patterns.py +================ + +Notes +----- + +The tests included within test_patterns.py are designed to torture the regular +expression programs used to match different parts of GTK-Doc comment blocks +by giscanner/annotationparser.py + + test_parser.py ============== diff --git a/tests/scanner/annotationparser/test_patterns.py b/tests/scanner/annotationparser/test_patterns.py new file mode 100644 index 00000000..0b5592a4 --- /dev/null +++ b/tests/scanner/annotationparser/test_patterns.py @@ -0,0 +1,590 @@ +# -*- Mode: Python -*- +# GObject-Introspection - a framework for introspecting GObject libraries +# Copyright (C) 2012 Dieter Verfaillie +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. +# + + +''' +test_patterns.py + +Tests ensuring the regular expression programs used +in annotationparser.py continue to function correctly. +Each regular expression program is tested on input that +should not match and input that should match. When input +should match, resulting symbolic groups are verified +against the expected output. +''' + + +from giscanner.annotationpatterns import (SECTION_RE, SYMBOL_RE, PROPERTY_RE, + SIGNAL_RE, PARAMETER_RE, TAG_RE) +from unittest import (TestCase, main) + + +identifier_section_tests = [ + (SECTION_RE, 'TSIEOCN', + None), + (SECTION_RE, 'section', + None), + (SECTION_RE, 'section:', + None), + (SECTION_RE, 'section:test', + None), + (SECTION_RE, 'SECTION', + {'colon': '', + 'section_name': None}), + (SECTION_RE, 'SECTION \t ', + {'colon': '', + 'section_name': None}), + (SECTION_RE, ' \t SECTION \t ', + {'colon': '', + 'section_name': None}), + (SECTION_RE, 'SECTION: \t ', + {'colon': ':', + 'section_name': None}), + (SECTION_RE, 'SECTION : ', + {'colon': ':', + 'section_name': None}), + (SECTION_RE, ' SECTION : ', + {'colon': ':', + 'section_name': None}), + (SECTION_RE, 'SECTION:gtkwidget', + {'colon': ':', + 'section_name': 'gtkwidget'}), + (SECTION_RE, 'SECTION:gtkwidget ', + {'colon': ':', + 'section_name': 'gtkwidget'}), + (SECTION_RE, ' SECTION:gtkwidget', + {'colon': ':', + 'section_name': 'gtkwidget'}), + (SECTION_RE, ' SECTION:gtkwidget\t ', + {'colon': ':', + 'section_name': 'gtkwidget'}), + (SECTION_RE, 'SECTION: gtkwidget ', + {'colon': ':', + 'section_name': 'gtkwidget'}), + (SECTION_RE, 'SECTION : gtkwidget', + {'colon': ':', + 'section_name': 'gtkwidget'}), + (SECTION_RE, 'SECTION gtkwidget \f ', + {'colon': '', + 'section_name': 'gtkwidget'})] + +identifier_symbol_tests = [ + (SYMBOL_RE, 'GBaseFinalizeFunc:', + {'colon': ':', + 'symbol_name': 'GBaseFinalizeFunc', + 'annotations': ''}), + (SYMBOL_RE, 'gtk_widget_show ', + {'colon': '', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, ' gtk_widget_show', + {'colon': '', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, ' gtk_widget_show ', + {'colon': '', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, 'gtk_widget_show:', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, 'gtk_widget_show :', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, 'gtk_widget_show: ', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, 'gtk_widget_show : ', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, ' gtk_widget_show:', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, ' gtk_widget_show :', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, ' gtk_widget_show: ', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, ' gtk_widget_show : ', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': ''}), + (SYMBOL_RE, 'gtk_widget_show (skip)', + {'colon': '', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip)'}), + (SYMBOL_RE, 'gtk_widget_show: (skip)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip)'}), + (SYMBOL_RE, 'gtk_widget_show : (skip)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip)'}), + (SYMBOL_RE, 'gtk_widget_show: (skip)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip)'}), + (SYMBOL_RE, 'gtk_widget_show : (skip)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip)'}), + (SYMBOL_RE, ' gtk_widget_show:(skip)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip)'}), + (SYMBOL_RE, ' gtk_widget_show :(skip)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip)'}), + (SYMBOL_RE, ' gtk_widget_show: (skip)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip)'}), + (SYMBOL_RE, ' gtk_widget_show : (skip) \t ', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) \t '}), + (SYMBOL_RE, ' gtk_widget_show : (skip) \t ', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) \t '}), + (SYMBOL_RE, 'gtk_widget_show:(skip)(test1)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip)(test1)'}), + (SYMBOL_RE, 'gtk_widget_show (skip)(test1)', + {'colon': '', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip)(test1)'}), + (SYMBOL_RE, 'gtk_widget_show: (skip) (test1)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1)'}), + (SYMBOL_RE, 'gtk_widget_show : (skip) (test1)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1)'}), + (SYMBOL_RE, 'gtk_widget_show: (skip) (test1)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1)'}), + (SYMBOL_RE, 'gtk_widget_show : (skip) (test1)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1)'}), + (SYMBOL_RE, ' gtk_widget_show:(skip) (test1)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1)'}), + (SYMBOL_RE, ' gtk_widget_show :(skip) (test1)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1)'}), + (SYMBOL_RE, ' gtk_widget_show: (skip) (test1)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1)'}), + (SYMBOL_RE, ' gtk_widget_show : (skip) (test1) ', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1) '}), + (SYMBOL_RE, 'gtk_widget_show: (skip) (test1) (test-2)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1) (test-2)'}), + (SYMBOL_RE, 'gtk_widget_show : (skip) (test1) (test-2)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1) (test-2)'}), + (SYMBOL_RE, 'gtk_widget_show: (skip) (test1) (test-2)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1) (test-2)'}), + (SYMBOL_RE, 'gtk_widget_show : (skip) (test1) (test-2)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1) (test-2)'}), + (SYMBOL_RE, ' gtk_widget_show:(skip) (test1) (test-2)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1) (test-2)'}), + (SYMBOL_RE, ' gtk_widget_show :(skip) (test1) (test-2)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1) (test-2)'}), + (SYMBOL_RE, ' gtk_widget_show: (skip) (test1) (test-2)', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1) (test-2)'}), + (SYMBOL_RE, ' gtk_widget_show : (skip) (test1) (test-2) ', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1) (test-2) '}), + (SYMBOL_RE, ' gtk_widget_show : (skip) (test1) (test-2) ', + {'colon': ':', + 'symbol_name': 'gtk_widget_show', + 'annotations': '(skip) (test1) (test-2) '}), + # constants + (SYMBOL_RE, 'MY_CONSTANT:', + {'colon': ':', + 'symbol_name': 'MY_CONSTANT', + 'annotations': ''}), + # structs + (SYMBOL_RE, 'FooWidget:', + {'colon': ':', + 'symbol_name': 'FooWidget', + 'annotations': ''}), + # enums + (SYMBOL_RE, 'Something:', + {'colon': ':', + 'symbol_name': 'Something', + 'annotations': ''})] + +identifier_property_tests = [ + # simple property name + (PROPERTY_RE, 'GtkWidget:name (skip)', + {'class_name': 'GtkWidget', + 'property_name': 'name', + 'colon': '', + 'annotations': '(skip)'}), + (PROPERTY_RE, 'GtkWidget:name', + {'class_name': 'GtkWidget', + 'property_name': 'name', + 'colon': '', + 'annotations': ''}), + (PROPERTY_RE, ' GtkWidget :name', + {'class_name': 'GtkWidget', + 'property_name': 'name', + 'colon': '', + 'annotations': ''}), + (PROPERTY_RE, 'GtkWidget: name ', + {'class_name': 'GtkWidget', + 'property_name': 'name', + 'colon': '', + 'annotations': ''}), + (PROPERTY_RE, ' GtkWidget : name ', + {'class_name': 'GtkWidget', + 'property_name': 'name', + 'colon': '', + 'annotations': ''}), + (PROPERTY_RE, 'GtkWidget:name:', + {'class_name': 'GtkWidget', + 'property_name': 'name', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, 'GtkWidget:name: ', + {'class_name': 'GtkWidget', + 'property_name': 'name', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, ' GtkWidget:name:', + {'class_name': 'GtkWidget', + 'property_name': 'name', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, 'Something:name:', + {'class_name': 'Something', + 'property_name': 'name', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, 'Something:name: ', + {'class_name': 'Something', + 'property_name': 'name', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, ' Something:name:', + {'class_name': 'Something', + 'property_name': 'name', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, 'Weird-thing:name:', + None), + (PROPERTY_RE, 'really-weird_thing:name:', + None), + (PROPERTY_RE, 'GWin32InputStream:handle:', + {'class_name': 'GWin32InputStream', + 'property_name': 'handle', + 'colon': ':', + 'annotations': ''}), + # property name that contains a dash + (PROPERTY_RE, 'GtkWidget:double-buffered (skip)', + {'class_name': 'GtkWidget', + 'property_name': 'double-buffered', + 'colon': '', + 'annotations': '(skip)'}), + (PROPERTY_RE, 'GtkWidget:double-buffered', + {'class_name': 'GtkWidget', + 'property_name': 'double-buffered', + 'colon': '', + 'annotations': ''}), + (PROPERTY_RE, ' GtkWidget :double-buffered', + {'class_name': 'GtkWidget', + 'property_name': 'double-buffered', + 'colon': '', + 'annotations': ''}), + (PROPERTY_RE, 'GtkWidget: double-buffered ', + {'class_name': 'GtkWidget', + 'property_name': 'double-buffered', + 'colon': '', + 'annotations': ''}), + (PROPERTY_RE, ' GtkWidget : double-buffered ', + {'class_name': 'GtkWidget', + 'property_name': 'double-buffered', + 'colon': '', + 'annotations': ''}), + (PROPERTY_RE, 'GtkWidget:double-buffered:', + {'class_name': 'GtkWidget', + 'property_name': 'double-buffered', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, 'GtkWidget:double-buffered: ', + {'class_name': 'GtkWidget', + 'property_name': 'double-buffered', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, ' GtkWidget:double-buffered:', + {'class_name': 'GtkWidget', + 'property_name': 'double-buffered', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, 'Something:double-buffered:', + {'class_name': 'Something', + 'property_name': 'double-buffered', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, 'Something:double-buffered: ', + {'class_name': 'Something', + 'property_name': 'double-buffered', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, ' Something:double-buffered:', + {'class_name': 'Something', + 'property_name': 'double-buffered', + 'colon': ':', + 'annotations': ''}), + (PROPERTY_RE, 'Weird-thing:double-buffered:', + None), + (PROPERTY_RE, 'really-weird_thing:double-buffered:', + None), + (PROPERTY_RE, ' GMemoryOutputStream:realloc-function: (skip)', + {'class_name': 'GMemoryOutputStream', + 'property_name': 'realloc-function', + 'colon': ':', + 'annotations': '(skip)'})] + +identifier_signal_tests = [ + # simple property name + (SIGNAL_RE, 'GtkWidget::changed: (skip)', + {'class_name': 'GtkWidget', + 'signal_name': 'changed', + 'colon': ':', + 'annotations': '(skip)'}), + (SIGNAL_RE, 'GtkWidget::changed:', + {'class_name': 'GtkWidget', + 'signal_name': 'changed', + 'colon': ':', + 'annotations': ''}), + (SIGNAL_RE, 'Something::changed:', + {'class_name': 'Something', + 'signal_name': 'changed', + 'colon': ':', + 'annotations': ''}), + (SIGNAL_RE, 'Weird-thing::changed:', + None), + (SIGNAL_RE, 'really-weird_thing::changed:', + None), + # signal name that contains a dash + (SIGNAL_RE, 'GtkWidget::hierarchy-changed: (skip)', + {'class_name': 'GtkWidget', + 'signal_name': 'hierarchy-changed', + 'colon': ':', + 'annotations': '(skip)'}), + (SIGNAL_RE, 'GtkWidget::hierarchy-changed:', + {'class_name': 'GtkWidget', + 'signal_name': 'hierarchy-changed', + 'colon': ':', + 'annotations': ''}), + (SIGNAL_RE, 'Something::hierarchy-changed:', + {'class_name': 'Something', + 'signal_name': 'hierarchy-changed', + 'colon': ':', + 'annotations': ''}), + (SIGNAL_RE, 'Weird-thing::hierarchy-changed:', + None), + (SIGNAL_RE, 'really-weird_thing::hierarchy-changed:', + None)] + +parameter_tests = [ + (PARAMETER_RE, '@Short_description: Base class for all widgets ', + {'parameter_name': 'Short_description', + 'annotations': '', + 'colon': '', + 'description': 'Base class for all widgets'}), + (PARAMETER_RE, '@...: the value of the first property, followed optionally by more', + {'parameter_name': '...', + 'annotations': '', + 'colon': '', + 'description': 'the value of the first property, followed optionally by more'}), + (PARAMETER_RE, '@widget: a #GtkWidget', + {'parameter_name': 'widget', + 'annotations': '', + 'colon': '', + 'description': 'a #GtkWidget'}), + (PARAMETER_RE, '@widget_pointer: (inout) (transfer none): ' + 'address of a variable that contains @widget', + {'parameter_name': 'widget_pointer', + 'annotations': '(inout) (transfer none)', + 'colon': ':', + 'description': 'address of a variable that contains @widget'}), + (PARAMETER_RE, '@weird_thing: (inout) (transfer none) (allow-none) (attribute) (destroy) ' + '(foreign) (inout) (out) (transfer) (skip) (method): some weird @thing', + {'parameter_name': 'weird_thing', + 'annotations': '(inout) (transfer none) (allow-none) (attribute) (destroy) ' + '(foreign) (inout) (out) (transfer) (skip) (method)', + 'colon': ':', + 'description': 'some weird @thing'}), + (PARAMETER_RE, '@data: a pointer to the element data. The data may be moved as elements ' + 'are added to the #GByteArray.', + {'parameter_name': 'data', + 'annotations': '', + 'colon': '', + 'description': 'a pointer to the element data. The data may be moved as elements ' + 'are added to the #GByteArray.'}), + (PARAMETER_RE, '@a: a #GSequenceIter', + {'parameter_name': 'a', + 'annotations': '', + 'colon': '', + 'description': 'a #GSequenceIter'}), + (PARAMETER_RE, '@keys: (array length=n_keys) (element-type GQuark) (allow-none):', + {'parameter_name': 'keys', + 'annotations': '(array length=n_keys) (element-type GQuark) (allow-none)', + 'colon': ':', + 'description': ''})] + +tag_tests = [ + (TAG_RE, 'Since 3.0', + None), + (TAG_RE, 'Since: 3.0', + {'tag_name': 'Since', + 'annotations': '', + 'colon': '', + 'description': '3.0'}), + (TAG_RE, 'Attributes: (inout) (transfer none): some note about attributes', + {'tag_name': 'Attributes', + 'annotations': '(inout) (transfer none)', + 'colon': ':', + 'description': 'some note about attributes'}), + (TAG_RE, 'Rename to: something_else', + {'tag_name': 'Rename to', + 'annotations': '', + 'colon': '', + 'description': 'something_else'}), + (TAG_RE, '@Deprecated: Since 2.8, reference counting is done atomically', + None), + (TAG_RE, 'Returns %TRUE and does weird things', + None), + (TAG_RE, 'Returns: a #GtkWidget', + {'tag_name': 'Returns', + 'annotations': '', + 'colon': '', + 'description': 'a #GtkWidget'}), + (TAG_RE, 'Return value: (transfer none): The binary data that @text responds. ' + 'This pointer', + {'tag_name': 'Return value', + 'annotations': '(transfer none)', + 'colon': ':', + 'description': 'The binary data that @text responds. This pointer'}), + (TAG_RE, 'Return value: (transfer full) (array length=out_len) (element-type guint8):', + {'tag_name': 'Return value', + 'annotations': '(transfer full) (array length=out_len) (element-type guint8)', + 'colon': ':', + 'description': ''}), + (TAG_RE, 'Returns: A boolean value, but let me tell you a bit about this boolean. It', + {'tag_name': 'Returns', + 'annotations': '', + 'colon': '', + 'description': 'A boolean value, but let me tell you a bit about this boolean. ' + 'It'}), + (TAG_RE, 'Returns: (transfer container) (element-type GObject.ParamSpec): a', + {'tag_name': 'Returns', + 'annotations': '(transfer container) (element-type GObject.ParamSpec)', + 'colon': ':', + 'description': 'a'}), + (TAG_RE, 'Return value: (type GLib.HashTable>) ' + '(transfer full):', + {'tag_name': 'Return value', + 'annotations': '(type GLib.HashTable>) ' + '(transfer full)', + 'colon': ':', + 'description': ''})] + + +def create_tests(tests_name, testcases): + for (index, testcase) in enumerate(testcases): + real_test_name = '%s_%03d' % (tests_name, index) + + test_method = TestProgram.__create_test__(testcase) + test_method.__name__ = real_test_name + setattr(TestProgram, real_test_name, test_method) + + +class TestProgram(TestCase): + @classmethod + def __create_test__(cls, testcase): + def do_test(self): + (program, text, expected) = testcase + + match = program.match(text) + + if expected is None: + msg = 'Program matched text but shouldn\'t:\n"%s"' + self.assertTrue(match is None, msg % (text, )) + else: + msg = 'Program should match text but didn\'t:\n"%s"' + self.assertTrue(match is not None, msg % (text, )) + + for key, value in expected.items(): + msg = 'expected "%s" for "%s" but match returned "%s"' + msg = msg % (value, key, match.group(key)) + self.assertEqual(match.group(key), value, msg) + + return do_test + + +if __name__ == '__main__': + # Create tests from data + create_tests('test_identifier_section', identifier_section_tests) + create_tests('test_identifier_symbol', identifier_symbol_tests) + create_tests('test_identifier_property', identifier_property_tests) + create_tests('test_identifier_signal', identifier_signal_tests) + create_tests('test_parameter', parameter_tests) + create_tests('test_tag', tag_tests) + + # Run test suite + main() -- cgit v1.2.1