summaryrefslogtreecommitdiff
path: root/grc/tests
diff options
context:
space:
mode:
authorSebastian Koslowski <sebastian.koslowski@gmail.com>2016-05-03 17:13:08 +0200
committerJohnathan Corgan <johnathan@corganlabs.com>2017-06-29 09:16:49 -0700
commit7f7fa2f91467fdb2b11312be8562e7b51fdeb199 (patch)
tree24268bac15b9920d2a15ddbb45eaf3b9b03718a1 /grc/tests
parent44cae388881821942e691a4d69a923bbd8d347db (diff)
grc: added yaml/mako support
Includes basic converter from XML/Cheetah to YAML/Mako based block format.
Diffstat (limited to 'grc/tests')
-rw-r--r--grc/tests/__init__.py0
-rw-r--r--grc/tests/resources/file1.xml58
-rw-r--r--grc/tests/resources/file2.xml80
-rw-r--r--grc/tests/resources/file3.xml100
-rw-r--r--grc/tests/test_block_flags.py26
-rw-r--r--grc/tests/test_block_templates.py45
-rw-r--r--grc/tests/test_cheetah_converter.py132
-rw-r--r--grc/tests/test_evaled_property.py104
-rw-r--r--grc/tests/test_expr_utils.py41
-rw-r--r--grc/tests/test_generator.py46
-rw-r--r--grc/tests/test_xml_parser.py39
-rw-r--r--grc/tests/test_yaml_checker.py84
12 files changed, 755 insertions, 0 deletions
diff --git a/grc/tests/__init__.py b/grc/tests/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/grc/tests/__init__.py
diff --git a/grc/tests/resources/file1.xml b/grc/tests/resources/file1.xml
new file mode 100644
index 0000000000..f03288b85d
--- /dev/null
+++ b/grc/tests/resources/file1.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<!--
+Copyright 2014 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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.
+
+GNU Radio Companion 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
+-->
+<block>
+ <name>testname</name>
+ <key>block_key</key>
+ <make>blocks.complex_to_mag_squared($(vlen))</make>
+ <param>
+ <name>Vec Length</name>
+ <key>vlen</key>
+ <value>1</value>
+ <type>int</type>
+ <tab>test</tab>
+ </param>
+ <param>
+ <name>Vec Length</name>
+ <key>out_type</key>
+ <value>complex</value>
+ <type>string</type>
+ </param>
+ <param>
+ <name>Alpha</name>
+ <key>a</key>
+ <value>0</value>
+ <type>($out_type)</type>
+ </param>
+ <check>$vlen &gt; 0</check>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ <vlen>2 * $vlen</vlen>
+ </sink>
+ <sink>
+ <name>in2</name>
+ <type>message</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$out_type</type>
+ <vlen>$vlen</vlen>
+ </source>
+</block>
diff --git a/grc/tests/resources/file2.xml b/grc/tests/resources/file2.xml
new file mode 100644
index 0000000000..1300c7f5a1
--- /dev/null
+++ b/grc/tests/resources/file2.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+Copyright 2014 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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.
+
+GNU Radio Companion 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
+-->
+<!--
+###################################################
+## And Const Block:
+## all types, 1 output, 1 input & const
+###################################################
+ -->
+<block>
+ <name>And Const</name>
+ <key>blocks_and_const_xx</key>
+ <category>test</category>
+ <throttle>1</throttle>
+ <import>from gnuradio import blocks</import>
+ <make>blocks.and_const_$(type.fcn)($const)</make>
+ <callback>set_k($const)</callback>
+ <param>
+ <name>IO Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Int</name>
+ <key>int</key>
+ <opt>fcn:ii</opt>
+ </option>
+ <option>
+ <name>Short</name>
+ <key>short</key>
+ <opt>fcn:ss</opt>
+ </option>
+ <option>
+ <name>Byte</name>
+ <key>byte</key>
+ <opt>fcn:bb</opt>
+ </option>
+ </param>
+ <param>
+ <name>Constant</name>
+ <key>const</key>
+ <value>0</value>
+ <type>${type}</type>
+ <hide>#if $log then 'none' else 'part'#</hide>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$(type.fcn)</type>
+ </source>
+ <doc>
+This block creates a variable check box. \
+Leave the label blank to use the variable id as the label.
+
+A check box selects between two values of similar type. \
+Te values do not necessarily need to be of boolean type.
+
+The GUI hint can be used to position the widget within the application. \
+The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \
+Both the tab specification and the grid position are optional.
+ </doc>
+</block>
diff --git a/grc/tests/resources/file3.xml b/grc/tests/resources/file3.xml
new file mode 100644
index 0000000000..71753badb1
--- /dev/null
+++ b/grc/tests/resources/file3.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0"?>
+<!--
+Copyright 2014 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion 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.
+
+GNU Radio Companion 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
+-->
+<!--
+###################################################
+##Variable Check Box:
+## a gui check box form
+###################################################
+ -->
+<block>
+ <name>QT GUI Check Box</name>
+ <key>variable_qtgui_check_box</key>
+ <import>from PyQt4 import Qt</import>
+ <var_make>self.$(id) = $(id) = $value</var_make>
+ <make>#set $win = '_%s_check_box'%$id
+#if not $label()
+ #set $label = '"%s"'%$id
+#end if
+$win = Qt.QCheckBox($label)
+self._$(id)_choices = {True: $true, False: $false}
+self._$(id)_choices_inv = dict((v,k) for k,v in self._$(id)_choices.iteritems())
+self._$(id)_callback = lambda i: Qt.QMetaObject.invokeMethod($(win), "setChecked", Qt.Q_ARG("bool", self._$(id)_choices_inv[i]))
+self._$(id)_callback(self.$id)
+$(win).stateChanged.connect(lambda i: self.set_$(id)(self._$(id)_choices[bool(i)]))
+$(gui_hint()($win))</make>
+ <callback>self.set_$(id)($value)</callback>
+ <callback>self._$(id)_callback($id)</callback>
+ <param>
+ <name>Label</name>
+ <key>label</key>
+ <value></value>
+ <type>string</type>
+ <hide>#if $label() then 'none' else 'part'#</hide>
+ </param>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <value>int</value>
+ <type>enum</type>
+ <hide>part</hide>
+ <option><name>Float</name><key>real</key><opt>conv:float</opt></option>
+ <option><name>Integer</name><key>int</key><opt>conv:int</opt></option>
+ <option><name>String</name><key>string</key><opt>conv:str</opt></option>
+ <option><name>Boolean</name><key>bool</key><opt>conv:bool</opt></option>
+ <option><name>Any</name><key>raw</key><opt>conv:eval</opt></option>
+ </param>
+ <param>
+ <name>Default Value</name>
+ <key>value</key>
+ <value>True</value>
+ <type>$type</type>
+ </param>
+ <param>
+ <name>True</name>
+ <key>true</key>
+ <value>True</value>
+ <type>$type</type>
+ </param>
+ <param>
+ <name>False</name>
+ <key>false</key>
+ <value>False</value>
+ <type>$type</type>
+ </param>
+ <param>
+ <name>GUI Hint</name>
+ <key>gui_hint</key>
+ <value></value>
+ <type>gui_hint</type>
+ <hide>part</hide>
+ </param>
+ <check>$value in ($true, $false)</check>
+ <doc>
+This block creates a variable check box. \
+Leave the label blank to use the variable id as the label.
+
+A check box selects between two values of similar type. \
+Te values do not necessarily need to be of boolean type.
+
+The GUI hint can be used to position the widget within the application. \
+The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \
+Both the tab specification and the grid position are optional.
+ </doc>
+</block>
diff --git a/grc/tests/test_block_flags.py b/grc/tests/test_block_flags.py
new file mode 100644
index 0000000000..9eecaf20d7
--- /dev/null
+++ b/grc/tests/test_block_flags.py
@@ -0,0 +1,26 @@
+
+from grc.core.blocks._flags import Flags
+
+
+def test_simple():
+ assert 'test' in Flags('_test_')
+
+
+def test_deprecated():
+ assert Flags.DEPRECATED == 'deprecated'
+ assert Flags('this is deprecated').deprecated is True
+
+
+def test_extend():
+ f = Flags('a')
+ f += 'b'
+ assert isinstance(f, Flags)
+ f += u'b'
+ assert isinstance(f, Flags)
+ f = Flags(u'a')
+ f += 'b'
+ assert isinstance(f, Flags)
+ f += u'b'
+ assert isinstance(f, Flags)
+
+ assert str(f) == 'abb'
diff --git a/grc/tests/test_block_templates.py b/grc/tests/test_block_templates.py
new file mode 100644
index 0000000000..df9ab37550
--- /dev/null
+++ b/grc/tests/test_block_templates.py
@@ -0,0 +1,45 @@
+import pytest
+
+from grc.core.blocks._templates import MakoTemplates
+from grc.core.errors import TemplateError
+
+
+class Block(object):
+ namespace_templates = {}
+
+ templates = MakoTemplates(None)
+
+ def __init__(self, **kwargs):
+ self.namespace_templates.update(kwargs)
+
+
+def test_simple():
+ t = MakoTemplates(_bind_to=Block(num='123'), test='abc${num}')
+ assert t['test'] == 'abc${num}'
+ assert t.render('test') == 'abc123'
+ assert 'abc${num}' in t._template_cache
+
+
+def test_instance():
+ block = Block(num='123')
+ block.templates['test'] = 'abc${num}'
+ assert block.templates.render('test') == 'abc123'
+ assert block.templates is block.__dict__['templates']
+
+
+def test_list():
+ templates = ['abc${num}', '${2 * num}c']
+ t = MakoTemplates(_bind_to=Block(num='123'), test=templates)
+ assert t['test'] == templates
+ assert t.render('test') == ['abc123', '123123c']
+ assert set(templates) == set(t._template_cache.keys())
+
+
+def test_parse_error():
+ with pytest.raises(TemplateError):
+ MakoTemplates(_bind_to=Block(num='123'), test='abc${num NOT CLOSING').render('test')
+
+
+def test_parse_error2():
+ with pytest.raises(TemplateError):
+ MakoTemplates(_bind_to=Block(num='123'), test='abc${ WRONG_VAR }').render('test')
diff --git a/grc/tests/test_cheetah_converter.py b/grc/tests/test_cheetah_converter.py
new file mode 100644
index 0000000000..7999955436
--- /dev/null
+++ b/grc/tests/test_cheetah_converter.py
@@ -0,0 +1,132 @@
+""""""
+
+import functools
+import grc.converter.cheetah_converter as parser
+
+
+def test_basic():
+ c = parser.Converter(names={'abc'})
+ for convert in (c.convert_simple, c.convert_hard, c.to_python):
+ assert 'abc' == convert('$abc')
+ assert 'abc' == convert('$abc()')
+ assert 'abc' == convert('$(abc)')
+ assert 'abc' == convert('$(abc())')
+ assert 'abc' == convert('${abc}')
+ assert 'abc' == convert('${abc()}')
+
+ assert c.stats['simple'] == 2 * 6
+ assert c.stats['hard'] == 1 * 6
+
+
+def test_simple():
+ convert = parser.Converter(names={'abc': {'def'}})
+ assert 'abc' == convert.convert_simple('$abc')
+ assert 'abc.def' == convert.convert_simple('$abc.def')
+ assert 'abc.def' == convert.convert_simple('$(abc.def)')
+ assert 'abc.def' == convert.convert_simple('${abc.def}')
+ try:
+ convert.convert_simple('$abc.not_a_sub_key')
+ except NameError:
+ assert True
+ else:
+ assert False
+
+
+def test_conditional():
+ convert = parser.Converter(names={'abc'})
+ assert '(asb_asd_ if abc > 0 else __not__)' == convert.convert_inline_conditional(
+ '#if $abc > 0 then asb_$asd_ else __not__')
+
+
+def test_simple_format_string():
+ convert = functools.partial(parser.Converter(names={'abc'}).convert_simple, spec=parser.FormatString)
+ assert '{abc}' == convert('$abc')
+ assert '{abc:eval}' == convert('$abc()')
+ assert '{abc}' == convert('$(abc)')
+ assert '{abc:eval}' == convert('$(abc())')
+ assert '{abc}' == convert('${abc}')
+ assert '{abc:eval}' == convert('${abc()}')
+
+
+def test_hard_format_string():
+ names = {'abc': {'ff'}, 'param1': {}, 'param2': {}}
+ convert = functools.partial(parser.Converter(names).convert_hard, spec=parser.FormatString)
+ assert 'make_a_cool_block_{abc.ff}({param1}, {param2})' == \
+ convert('make_a_cool_block_${abc.ff}($param1, $param2)')
+
+
+converter = parser.Converter(names={'abc'})
+c2p = converter.to_python
+
+
+def test_opts():
+ assert 'abc abc abc' == c2p('$abc $(abc) ${abc}')
+ assert 'abc abc.abc abc' == c2p('$abc $abc.abc ${abc}')
+ assert 'abc abc[''].abc abc' == c2p('$abc $abc[''].abc() ${abc}')
+
+
+def test_nested():
+ assert 'abc(abc) abc + abc abc[abc]' == c2p('$abc($abc) $(abc + $abc) ${abc[$abc]}')
+ assert '(abc_abc_)' == c2p('(abc_$(abc)_)')
+
+
+def test_nested2():
+ class Other(parser.Python):
+ nested_start = '{'
+ nested_end = '}'
+ assert 'abc({abc})' == converter.convert('$abc($abc)', spec=Other)
+
+
+def test_nested3():
+ class Other(parser.Python):
+ start = '{'
+ end = '}'
+ assert '{abc(abc)}' == converter.convert('$abc($abc)', spec=Other)
+
+
+def test_with_string():
+ assert 'abc "$(abc)" abc' == c2p('$abc "$(abc)" ${abc}')
+ assert 'abc \'$(abc)\' abc' == c2p('$abc \'$(abc)\' ${abc}')
+ assert 'abc "\'\'$(abc)" abc' == c2p('$abc "\'\'$(abc)" ${abc}')
+
+
+def test_if():
+ result = converter.to_mako("""
+ #if $abc > 0
+ test
+ #else if $abc < 0
+ test
+ #else
+ bla
+ #end if
+ """)
+
+ expected = """
+ % if abc > 0:
+ test
+ % elif abc < 0:
+ test
+ % else:
+ bla
+ % endif
+ """
+ assert result == expected
+
+
+def test_hash_end():
+ result = converter.to_mako('$abc#slurp')
+ assert result == '${abc}\\'
+
+
+def test_slurp_if():
+ result = converter.to_mako("""
+ $abc#slurp
+ #if $abc
+ """)
+
+ expected = """
+ ${abc}
+ % if abc:
+ """
+ assert result == expected
+
diff --git a/grc/tests/test_evaled_property.py b/grc/tests/test_evaled_property.py
new file mode 100644
index 0000000000..27957cd291
--- /dev/null
+++ b/grc/tests/test_evaled_property.py
@@ -0,0 +1,104 @@
+import collections
+import numbers
+
+from grc.core.utils.descriptors import Evaluated, EvaluatedEnum, EvaluatedPInt
+
+
+class A(object):
+ def __init__(self, **kwargs):
+ self.called = collections.defaultdict(int)
+ self.errors = []
+ self.namespace = kwargs
+
+ def add_error_message(self, msg):
+ self.errors.append(msg)
+
+ @property
+ def parent_block(self):
+ return self
+
+ def evaluate(self, expr):
+ self.called['evaluate'] += 1
+ return eval(expr, self.namespace)
+
+ @Evaluated(int, 1)
+ def foo(self):
+ self.called['foo'] += 1
+ return eval(self._foo)
+
+ bar = Evaluated(numbers.Real, 1.0, name='bar')
+
+ test = EvaluatedEnum(['a', 'b'], 'a', name='test')
+
+ lala = EvaluatedPInt()
+
+
+def test_fixed_value():
+ a = A()
+ a.foo = 10
+
+ assert not hasattr(a, '_foo')
+ assert a.foo == 10
+ assert a.called['foo'] == 0
+ delattr(a, 'foo')
+ assert a.foo == 10
+ assert a.called['foo'] == 0
+
+
+def test_evaled():
+ a = A()
+ a.foo = '${ 10 + 1 }'
+ assert getattr(a, '_foo') == '10 + 1'
+ assert a.foo == 11 and a.foo == 11
+ assert a.called['foo'] == 1
+ assert a.called['evaluate'] == 0
+ delattr(a, 'foo')
+ assert a.foo == 11 and a.foo == 11
+ assert a.called['foo'] == 2
+ assert not a.errors
+
+
+def test_evaled_with_default():
+ a = A()
+ a.bar = '${ 10 + 1 }'
+ assert getattr(a, '_bar') == '10 + 1'
+ assert a.bar == 11.0 and type(a.bar) == int
+ assert a.called['evaluate'] == 1
+ assert not a.errors
+
+
+def test_evaled_int_with_default():
+ a = A(ll=10)
+ a.lala = '${ ll * 2 }'
+ assert a.lala == 20
+ a.namespace['ll'] = -10
+ assert a.lala == 20
+ del a.lala
+ assert a.lala == 1
+ assert not a.errors
+
+
+def test_evaled_enum_fixed_value():
+ a = A()
+ a.test = 'a'
+ assert not hasattr(a, '_test')
+ assert a.test == 'a' and type(a.test) == str
+ assert not a.errors
+
+
+def test_evaled_enum():
+ a = A(bla=False)
+ a.test = '${ "a" if bla else "b" }'
+ assert a.test == 'b'
+ a.namespace['bla'] = True
+ assert a.test == 'b'
+ del a.test
+ assert a.test == 'a'
+ assert not a.errors
+
+
+def test_class_access():
+ a = A()
+ a.foo = '${ meme }'
+ descriptor = getattr(a.__class__, 'foo')
+ assert descriptor.name_raw == '_foo'
diff --git a/grc/tests/test_expr_utils.py b/grc/tests/test_expr_utils.py
new file mode 100644
index 0000000000..4f25477bf1
--- /dev/null
+++ b/grc/tests/test_expr_utils.py
@@ -0,0 +1,41 @@
+import operator
+
+import pytest
+
+from grc.core.utils import expr_utils
+
+id_getter = operator.itemgetter(0)
+expr_getter = operator.itemgetter(1)
+
+
+def test_simple():
+ objects = [
+ ['c', '2 * a + b'],
+ ['a', '1'],
+ ['b', '2 * a + unknown * d'],
+ ['d', '5'],
+ ]
+
+ expected = [
+ ['a', '1'],
+ ['d', '5'],
+ ['b', '2 * a + unknown * d'],
+ ['c', '2 * a + b'],
+ ]
+
+ out = expr_utils.sort_objects2(objects, id_getter, expr_getter)
+
+ assert out == expected
+
+
+def test_other():
+ test = [
+ ['c', '2 * a + b'],
+ ['a', '1'],
+ ['b', '2 * c + unknown'],
+ ]
+
+ expr_utils.sort_objects2(test, id_getter, expr_getter, check_circular=False)
+
+ with pytest.raises(RuntimeError):
+ expr_utils.sort_objects2(test, id_getter, expr_getter)
diff --git a/grc/tests/test_generator.py b/grc/tests/test_generator.py
new file mode 100644
index 0000000000..4c79ce4bd3
--- /dev/null
+++ b/grc/tests/test_generator.py
@@ -0,0 +1,46 @@
+# Copyright 2016 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+from os import path
+import tempfile
+
+from grc.core.platform import Platform
+
+
+def test_generator():
+ # c&p form compiler code.
+ # todo: make this independent from installed GR
+ grc_file = path.join(path.dirname(__file__), 'resources', 'test_compiler.grc')
+ out_dir = tempfile.gettempdir()
+
+ platform = Platform(
+ name='GNU Radio Companion Compiler',
+ prefs=None,
+ version='0.0.0',
+ )
+ platform.build_library()
+
+ flow_graph = platform.make_flow_graph(grc_file)
+ flow_graph.rewrite()
+ flow_graph.validate()
+
+ assert flow_graph.is_valid()
+
+ generator = platform.Generator(flow_graph, path.join(path.dirname(__file__), 'resources'))
+ generator.write()
diff --git a/grc/tests/test_xml_parser.py b/grc/tests/test_xml_parser.py
new file mode 100644
index 0000000000..c68b6cdc5a
--- /dev/null
+++ b/grc/tests/test_xml_parser.py
@@ -0,0 +1,39 @@
+# Copyright 2017 Free Software Foundation, Inc.
+# This file is part of GNU Radio
+#
+# GNU Radio Companion 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.
+#
+# GNU Radio Companion 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
+
+from os import path
+import sys
+
+from grc.converter import flow_graph
+
+
+def test_flow_graph_converter():
+ filename = path.join(path.dirname(__file__), 'resources', 'test_compiler.grc')
+
+ data = flow_graph.from_xml(filename)
+
+ flow_graph.dump(data, sys.stdout)
+
+
+def test_flow_graph_converter_with_fp():
+ filename = path.join(path.dirname(__file__), 'resources', 'test_compiler.grc')
+
+ with open(filename) as fp:
+ data = flow_graph.from_xml(fp)
+
+ flow_graph.dump(data, sys.stdout)
+
diff --git a/grc/tests/test_yaml_checker.py b/grc/tests/test_yaml_checker.py
new file mode 100644
index 0000000000..e6b466e511
--- /dev/null
+++ b/grc/tests/test_yaml_checker.py
@@ -0,0 +1,84 @@
+# Copyright 2016 Free Software Foundation, Inc.
+# This file is part of GNU Radio
+#
+# GNU Radio Companion 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.
+#
+# GNU Radio Companion 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
+
+import yaml
+
+from grc.core.schema_checker import Validator, BLOCK_SCHEME
+
+
+BLOCK1 = """
+id: block_key
+label: testname
+
+parameters:
+- id: vlen
+ label: Vec Length
+ dtype: int
+ default: 1
+- id: out_type
+ label: Vec Length
+ dtype: string
+ default: complex
+- id: a
+ label: Alpha
+ dtype: ${ out_type }
+ default: '0'
+
+inputs:
+- label: in
+ domain: stream
+ dtype: complex
+ vlen: ${ 2 * vlen }
+- name: in2
+ domain: message
+ id: in2
+
+outputs:
+- label: out
+ domain: stream
+ dtype: ${ out_type }
+ vlen: ${ vlen }
+
+templates:
+ make: blocks.complex_to_mag_squared(${ vlen })
+
+file_format: 1
+"""
+
+
+def test_min():
+ checker = Validator(BLOCK_SCHEME)
+ assert checker.run({'id': 'test', 'file_format': 1}), checker.messages
+ assert not checker.run({'name': 'test', 'file_format': 1})
+
+
+def test_extra_keys():
+ checker = Validator(BLOCK_SCHEME)
+ assert checker.run({'id': 'test', 'abcdefg': 'nonsense', 'file_format': 1})
+ assert checker.messages == [('block', 'warn', "Ignoring extra key 'abcdefg'")]
+
+
+def test_checker():
+ checker = Validator(BLOCK_SCHEME)
+ data = yaml.load(BLOCK1)
+ passed = checker.run(data)
+ if not passed:
+ print()
+ for msg in checker.messages:
+ print(msg)
+
+ assert passed, checker.messages