diff --git a/spinn_utilities/default_ordered_dict.py b/spinn_utilities/default_ordered_dict.py index 3ff39510..5e4f29e3 100644 --- a/spinn_utilities/default_ordered_dict.py +++ b/spinn_utilities/default_ordered_dict.py @@ -44,19 +44,18 @@ def __reduce__(self): args = tuple() else: args = self.default_factory, - return type(self), args, None, None, self.items() + return type(self), args, None, None, iter(self.items()) def copy(self): - return self.__copy__() + return type(self)(self.default_factory, self.items()) - def __copy__(self): - return type(self)(self.default_factory, self) + __copy__ = copy def __deepcopy__(self, memo): import copy return type(self)(self.default_factory, - copy.deepcopy(self.items())) + copy.deepcopy(iter(self.items()))) def __repr__(self): - return 'OrderedDefaultDict(%s, %s)' % ( + return 'DefaultOrderedDict(%s, %s)' % ( self.default_factory, OrderedDict.__repr__(self)) diff --git a/spinn_utilities/make_tools/file_converter.py b/spinn_utilities/make_tools/file_converter.py index 168cee0f..f76590ce 100644 --- a/spinn_utilities/make_tools/file_converter.py +++ b/spinn_utilities/make_tools/file_converter.py @@ -424,16 +424,13 @@ def _short_log(self, line_num): front += TOKEN if match.endswith("f"): front += "%x" - elif match.endswith("F"): - front += "%x" + TOKEN + "%x" - else: - front += match - if match.endswith("f"): back += ", float_to_int({})".format(parts[i + 1]) elif match.endswith("F"): + front += "%x" + TOKEN + "%x" back += DOUBLE_HEX.format(parts[i + 1]) else: - back += ", {}".format(parts[i+1]) + front += match + back += ", {}".format(parts[i + 1]) front += '", {}'.format(self._message_id) back += ");" return original, front + back diff --git a/spinn_utilities/ordered_set.py b/spinn_utilities/ordered_set.py index 1931133f..e63d2475 100644 --- a/spinn_utilities/ordered_set.py +++ b/spinn_utilities/ordered_set.py @@ -52,7 +52,7 @@ def peek(self, last=True): if last: return next(reversed(self)) else: - return next(self) + return next(iter(self)) def __len__(self): return len(self._map) diff --git a/unittests/make_tools/mock_src/weird,file.c b/unittests/make_tools/mock_src/weird,file.c index 3361aaef..01fd1ed4 100644 --- a/unittests/make_tools/mock_src/weird,file.c +++ b/unittests/make_tools/mock_src/weird,file.c @@ -30,6 +30,10 @@ static String woops = "log_info("; log_info("test -three %f", -3.0f); + log_info("test double %F", -3.0d); + + log_info("test slash // %f", 3/2); + log_info("this is ok"); //log_info("this is just a comment"); @@ -99,6 +103,9 @@ static String woops = "log_info("; ds_regions->version >> VERSION_SHIFT, ds_regions->version & VERSION_MASK); + log_inf("blah", + ")", + "more"); /* comment */ log_info("comment before"); fluff fluff diff --git a/unittests/make_tools/test.dict b/unittests/make_tools/test.dict index 629456f9..64387737 100644 --- a/unittests/make_tools/test.dict +++ b/unittests/make_tools/test.dict @@ -8,6 +8,9 @@ Id,Preface,Original 1006,[INFO] (weird;file.c: 25): ,Test %u for alan); so there! 1007,[INFO] (weird;file.c: 29): ,\t back off = %u, time between spikes %u 1008,[DEBUG] (weird;file.c: 33): ,the neuron %d has been determined to not spike +A weird lone got in +Another, weird, line, got, in +And one, with, three parts 1009,[WARNING] (weird;file.c: 37): ,Inside a loop 1010,[INFO] (weird;file.c: 39): ,then a space 1011,[INFO] (weird;file.c: 42): ,then a newline simple @@ -20,3 +23,5 @@ Id,Preface,Original 1018,[DEBUG] (bit_field.c: 71): ,%c 1019,[DEBUG] (bit_field.c: 75): ,\n 1020,[DEBUG] (bit_field.c: 111): ,%08x\n +1021,[INFO] (weird;file.c: 32):, a float %f +1022,[INFO] (weird;file.c: 34):, a double %F diff --git a/unittests/make_tools/test_file_convert.py b/unittests/make_tools/test_file_convert.py index 744c9a63..24f7e14d 100644 --- a/unittests/make_tools/test_file_convert.py +++ b/unittests/make_tools/test_file_convert.py @@ -60,3 +60,38 @@ def test_convert(self): assert("then a backslash comment on a middle line" in data) assert("then a standard comment on a middle line" in data) assert("comment before" in data) + + def test_exceptions(self): + file_name = "weird,file.c" + src = os.path.join("mock_src", file_name) + dest = os.path.join("modified_src", file_name) + dict = dest + "dict" + convertor = FileConverter(src, dest, dict) + try: + convertor.split_by_comma_plus(None, 12) + assert False + except Exception as ex1: + assert "Unexpected line" in str(ex1) + try: + convertor._short_log(12) + assert False + except Exception as ex2: + assert "Unexpected line" in str(ex2) + try: + convertor._log_full = '"test %f", -3.0f, 12);' + convertor._short_log(12) + assert False + except Exception as ex2: + assert "Too many" in str(ex2) + try: + convertor._log_full = '"test %f %i", -3.0f);' + convertor._short_log(12) + assert False + except Exception as ex2: + assert "Too few" in str(ex2) + try: + convertor._log_full = '"test %1", -3.0f);' + convertor._short_log(12) + assert False + except Exception as ex2: + assert "Unexpected formatString" in str(ex2) diff --git a/unittests/make_tools/test_replacer.py b/unittests/make_tools/test_replacer.py index 290e5b72..d22e75ea 100644 --- a/unittests/make_tools/test_replacer.py +++ b/unittests/make_tools/test_replacer.py @@ -45,6 +45,26 @@ def test_tab(self): " spikes 20" assert (message == new) + def test_float(self): + replacer = Replacer(os.path.join(PATH, "test")) + new = replacer.replace("1021" + TOKEN + "3f800000") + message = "[INFO] (weird;file.c: 32): a float 1.0" + assert (message == new) + + def test_double(self): + replacer = Replacer(os.path.join(PATH, "test")) + new = replacer.replace( + "1022" + TOKEN + "40379999" + TOKEN + "9999999a") + message = "[INFO] (weird;file.c: 34): a double 23.6" + assert (message == new) + + def test_bad(self): + replacer = Replacer(os.path.join(PATH, "test")) + new = replacer.replace("1007" + TOKEN + "10") + # An exception so just output the input + message = "1007" + TOKEN + "10" + assert (message == new) + def near_equals(self, a, b): diff = a - b if diff == 0: diff --git a/unittests/matrix/test_double.py b/unittests/matrix/test_double.py index 6efa71fa..2e54c083 100644 --- a/unittests/matrix/test_double.py +++ b/unittests/matrix/test_double.py @@ -50,3 +50,39 @@ def test_singleSet_inverted(): double[1] = new_data assert double["foo"][1] == "One" assert double[1]["bar"] == "Two" + + +def test_errors(): + matrix = DemoMatrix() + double = DoubleDict(xtype=str, ytype=int, matrix=matrix) + new_data = {"foo": "One", "bar": "Two"} + double[1] = new_data + try: + double[1.1] + assert False + except KeyError as ex: + assert "unexpected type" in str(ex) + try: + double["Bar"] = "Opps" + except ValueError as ex: + assert "Value must of type dict" in str(ex) + try: + double["Bar"] = [2, "Opps"] + assert False + except ValueError as ex: + assert "Value must of type dict" in str(ex) + try: + double["Bar"] = {2.1: "Opps"} + assert False + except ValueError as ex: + assert "All keys in the value" in str(ex) + try: + double[2] = {1: "Opps"} + assert False + except ValueError as ex: + assert "All keys in the value" in str(ex) + try: + double[2.1] = {1: "Opps"} + assert False + except KeyError as ex: + assert "unexpected type" in str(ex) diff --git a/unittests/test_conf_loader.py b/unittests/test_conf_loader.py index 344ea88e..2243bcf8 100644 --- a/unittests/test_conf_loader.py +++ b/unittests/test_conf_loader.py @@ -119,6 +119,27 @@ def test_new_section_validation(tmpdir, default_config): conf_loader.load_config(CFGFILE, [CFGPATH], validation_cfg="blank.cfg") +def test_types(tmpdir, default_config): + with tmpdir.as_cwd(): + f = tmpdir.join(CFGFILE) + default_config = ( + default_config + + "[machine]\nmachineName=foo\nVersion=5\nsize=4.6\nb1=True\n" + "b2=true\nb3=False\nb4=False\nOops=None\n") + f.write(default_config) + config = conf_loader.load_config( + CFGFILE, [CFGPATH], validation_cfg="blank.cfg") + assert config.get_int("machine", "version") == 5 + assert config.get_int("machine", "oops") is None + assert config.get_float("machine", "size") == 4.6 + assert config.get_float("machine", "oops") is None + assert config.get_bool("machine", "b1") + assert config.get_bool("machine", "b2") + assert not config.get_bool("machine", "b3") + assert not config.get_bool("machine", "b4") + assert config.get_bool("machine", "oops") is None + + def test_dead_section(tmpdir, default_config): with tmpdir.as_cwd(): f = tmpdir.join(CFGFILE) diff --git a/unittests/test_default_ordered_dict.py b/unittests/test_default_ordered_dict.py index 35eef51b..33d99a61 100644 --- a/unittests/test_default_ordered_dict.py +++ b/unittests/test_default_ordered_dict.py @@ -13,6 +13,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import copy +import pickle import pytest from spinn_utilities.default_ordered_dict import DefaultOrderedDict from spinn_utilities.ordered_set import OrderedSet @@ -53,3 +55,26 @@ def test_keys_in_order(): c = o["c"] assert a == b == c assert tuple(o) == ("a", "b", "c") + + +def test_callable(): + try: + DefaultOrderedDict("Not callable") + assert False + except TypeError: + pass + + +def test_special_methods(): + o = DefaultOrderedDict(list) + o["gamma"].append("bacon") + # test _-reduce + pickle.dumps(o) + # test copy + o2 = o.copy() + assert o2["gamma"] == ["bacon"] + o3 = copy.deepcopy(o) + assert o3["gamma"] == ["bacon"] + a = repr(o) + b = repr(o3) + assert a == b diff --git a/unittests/test_index_is_value.py b/unittests/test_index_is_value.py new file mode 100644 index 00000000..dada43d5 --- /dev/null +++ b/unittests/test_index_is_value.py @@ -0,0 +1,22 @@ +# Copyright (c) 2017-2018 The University of Manchester +# +# 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 3 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, see . + +from spinn_utilities.index_is_value import IndexIsValue + + +def test_index_is_value(): + a = IndexIsValue() + assert a[10] == 10 + assert len(a) > 1000 diff --git a/unittests/test_log.py b/unittests/test_log.py index feab4a32..04e94709 100644 --- a/unittests/test_log.py +++ b/unittests/test_log.py @@ -15,6 +15,7 @@ import logging import tempfile +from spinn_utilities.log import (ConfiguredFilter, ConfiguredFormatter) from spinn_utilities.log import FormatAdapter, LogLevelTooHighException @@ -98,6 +99,37 @@ class Exn(Exception): assert len(logger._repeat_log()) == 1 +class MockConfig1(object): + + def get(self, section, option): + return "debug" + + def has_section(self, section): + return False + + +def test_weird_config1(): + ConfiguredFormatter(MockConfig1()) + ConfiguredFilter(MockConfig1()) + + +class MockConfig2(object): + + def get(self, section, option): + return "critical" + + def has_section(self, section): + return True + + def has_option(self, section, option): + return option == 'warning' + + +def test_weird_config2(): + ConfiguredFormatter(MockConfig2()) + ConfiguredFilter(MockConfig2()) + + def test_waning_file(): log = MockLog() logger = FormatAdapter(log) diff --git a/unittests/test_logger_utils.py b/unittests/test_logger_utils.py index d948eb33..c6c06e54 100644 --- a/unittests/test_logger_utils.py +++ b/unittests/test_logger_utils.py @@ -63,6 +63,7 @@ def test_error(self): logger_utils.error_once(logger, "a log Error") logger_utils.warn_once(logger, "another log error") logger_utils.warn_once(logger, "a log warning") + logger_utils.error_once(logger, "a log Error") log_checker.assert_logs_contains_once( "ERROR", lc.records, "a log Error") log_checker.assert_logs_error_not_contains( diff --git a/unittests/test_ordered_set.py b/unittests/test_ordered_set.py index 96c1eba0..1e77f132 100644 --- a/unittests/test_ordered_set.py +++ b/unittests/test_ordered_set.py @@ -139,4 +139,19 @@ def test_peek(): o.add(2) o.add(3) p1 = o.peek() + p2 = o.pop() assert p1 == 3 + assert p1 == p2 + p3 = o.peek(last=False) + assert p3 == 1 + p4 = o.pop(last=False) + assert p4 == p3 + + +def test_reverse(): + o = OrderedSet() + o.add(1) + o.add(2) + o.add(3) + a = list(reversed(o)) + assert a == [3, 2, 1]