diff options
author | Sebastian Koslowski <sebastian.koslowski@gmail.com> | 2016-05-03 17:13:08 +0200 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2017-06-29 09:16:49 -0700 |
commit | 7f7fa2f91467fdb2b11312be8562e7b51fdeb199 (patch) | |
tree | 24268bac15b9920d2a15ddbb45eaf3b9b03718a1 /grc/tests | |
parent | 44cae388881821942e691a4d69a923bbd8d347db (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__.py | 0 | ||||
-rw-r--r-- | grc/tests/resources/file1.xml | 58 | ||||
-rw-r--r-- | grc/tests/resources/file2.xml | 80 | ||||
-rw-r--r-- | grc/tests/resources/file3.xml | 100 | ||||
-rw-r--r-- | grc/tests/test_block_flags.py | 26 | ||||
-rw-r--r-- | grc/tests/test_block_templates.py | 45 | ||||
-rw-r--r-- | grc/tests/test_cheetah_converter.py | 132 | ||||
-rw-r--r-- | grc/tests/test_evaled_property.py | 104 | ||||
-rw-r--r-- | grc/tests/test_expr_utils.py | 41 | ||||
-rw-r--r-- | grc/tests/test_generator.py | 46 | ||||
-rw-r--r-- | grc/tests/test_xml_parser.py | 39 | ||||
-rw-r--r-- | grc/tests/test_yaml_checker.py | 84 |
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 > 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 |