2 # This Source Code Form is subject to the terms of the Mozilla Public
3 # License, v. 2.0. If a copy of the MPL was not distributed with this
4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
16 from mozfile
.mozfile
import NamedTemporaryFile
17 from mozunit
import main
19 from mozbuild
.util
import (
21 EnumStringComparisonError
,
22 HierarchicalStringList
,
23 MozbuildDeletionError
,
25 StrictOrderingOnAppendList
,
26 StrictOrderingOnAppendListWithAction
,
27 StrictOrderingOnAppendListWithFlagsFactory
,
38 resolve_target_to_make
,
41 if sys
.version_info
[0] == 3:
46 data_path
= os
.path
.abspath(os
.path
.dirname(__file__
))
47 data_path
= os
.path
.join(data_path
, "data")
50 class TestHashing(unittest
.TestCase
):
51 def test_hash_file_known_hash(self
):
52 """Ensure a known hash value is recreated."""
53 data
= b
"The quick brown fox jumps over the lazy cog"
54 expected
= "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3"
56 temp
= NamedTemporaryFile()
60 actual
= hash_file(temp
.name
)
62 self
.assertEqual(actual
, expected
)
64 def test_hash_file_large(self
):
65 """Ensure that hash_file seems to work with a large file."""
68 hasher
= hashlib
.sha1()
70 expected
= hasher
.hexdigest()
72 temp
= NamedTemporaryFile()
76 actual
= hash_file(temp
.name
)
78 self
.assertEqual(actual
, expected
)
81 class TestResolveTargetToMake(unittest
.TestCase
):
83 self
.topobjdir
= data_path
85 def assertResolve(self
, path
, expected
):
86 # Handle Windows path separators.
87 (reldir
, target
) = resolve_target_to_make(self
.topobjdir
, path
)
88 if reldir
is not None:
89 reldir
= reldir
.replace(os
.sep
, "/")
90 if target
is not None:
91 target
= target
.replace(os
.sep
, "/")
92 self
.assertEqual((reldir
, target
), expected
)
94 def test_root_path(self
):
95 self
.assertResolve("/test-dir", ("test-dir", None))
96 self
.assertResolve("/test-dir/with", ("test-dir/with", None))
97 self
.assertResolve("/test-dir/without", ("test-dir", None))
98 self
.assertResolve("/test-dir/without/with", ("test-dir/without/with", None))
101 self
.assertResolve("test-dir", ("test-dir", None))
102 self
.assertResolve("test-dir/with", ("test-dir/with", None))
103 self
.assertResolve("test-dir/with", ("test-dir/with", None))
104 self
.assertResolve("test-dir/without", ("test-dir", None))
105 self
.assertResolve("test-dir/without/with", ("test-dir/without/with", None))
107 def test_top_level(self
):
108 self
.assertResolve("package", (None, "package"))
109 # Makefile handling shouldn't affect top-level targets.
110 self
.assertResolve("Makefile", (None, "Makefile"))
112 def test_regular_file(self
):
113 self
.assertResolve("test-dir/with/file", ("test-dir/with", "file"))
115 "test-dir/with/without/file", ("test-dir/with", "without/file")
118 "test-dir/with/without/with/file", ("test-dir/with/without/with", "file")
121 self
.assertResolve("test-dir/without/file", ("test-dir", "without/file"))
123 "test-dir/without/with/file", ("test-dir/without/with", "file")
126 "test-dir/without/with/without/file",
127 ("test-dir/without/with", "without/file"),
130 def test_Makefile(self
):
131 self
.assertResolve("test-dir/with/Makefile", ("test-dir", "with/Makefile"))
133 "test-dir/with/without/Makefile", ("test-dir/with", "without/Makefile")
136 "test-dir/with/without/with/Makefile",
137 ("test-dir/with", "without/with/Makefile"),
141 "test-dir/without/Makefile", ("test-dir", "without/Makefile")
144 "test-dir/without/with/Makefile", ("test-dir", "without/with/Makefile")
147 "test-dir/without/with/without/Makefile",
148 ("test-dir/without/with", "without/Makefile"),
152 class TestHierarchicalStringList(unittest
.TestCase
):
154 self
.EXPORTS
= HierarchicalStringList()
156 def test_exports_append(self
):
157 self
.assertEqual(self
.EXPORTS
._strings
, [])
158 self
.EXPORTS
+= ["foo.h"]
159 self
.assertEqual(self
.EXPORTS
._strings
, ["foo.h"])
160 self
.EXPORTS
+= ["bar.h"]
161 self
.assertEqual(self
.EXPORTS
._strings
, ["foo.h", "bar.h"])
163 def test_exports_subdir(self
):
164 self
.assertEqual(self
.EXPORTS
._children
, {})
165 self
.EXPORTS
.foo
+= ["foo.h"]
166 six
.assertCountEqual(self
, self
.EXPORTS
._children
, {"foo": True})
167 self
.assertEqual(self
.EXPORTS
.foo
._strings
, ["foo.h"])
168 self
.EXPORTS
.bar
+= ["bar.h"]
169 six
.assertCountEqual(self
, self
.EXPORTS
._children
, {"foo": True, "bar": True})
170 self
.assertEqual(self
.EXPORTS
.foo
._strings
, ["foo.h"])
171 self
.assertEqual(self
.EXPORTS
.bar
._strings
, ["bar.h"])
173 def test_exports_multiple_subdir(self
):
174 self
.EXPORTS
.foo
.bar
= ["foobar.h"]
175 six
.assertCountEqual(self
, self
.EXPORTS
._children
, {"foo": True})
176 six
.assertCountEqual(self
, self
.EXPORTS
.foo
._children
, {"bar": True})
177 six
.assertCountEqual(self
, self
.EXPORTS
.foo
.bar
._children
, {})
178 self
.assertEqual(self
.EXPORTS
._strings
, [])
179 self
.assertEqual(self
.EXPORTS
.foo
._strings
, [])
180 self
.assertEqual(self
.EXPORTS
.foo
.bar
._strings
, ["foobar.h"])
182 def test_invalid_exports_append(self
):
183 with self
.assertRaises(ValueError) as ve
:
184 self
.EXPORTS
+= "foo.h"
188 "Expected a list of strings, not <(?:type|class) '%s'>" % str_type
,
191 def test_invalid_exports_set(self
):
192 with self
.assertRaises(ValueError) as ve
:
193 self
.EXPORTS
.foo
= "foo.h"
198 "Expected a list of strings, not <(?:type|class) '%s'>" % str_type
,
201 def test_invalid_exports_append_base(self
):
202 with self
.assertRaises(ValueError) as ve
:
203 self
.EXPORTS
+= "foo.h"
208 "Expected a list of strings, not <(?:type|class) '%s'>" % str_type
,
211 def test_invalid_exports_bool(self
):
212 with self
.assertRaises(ValueError) as ve
:
213 self
.EXPORTS
+= [True]
218 "Expected a list of strings, not an element of " "<(?:type|class) 'bool'>",
221 def test_del_exports(self
):
222 with self
.assertRaises(MozbuildDeletionError
):
223 self
.EXPORTS
.foo
+= ["bar.h"]
226 def test_unsorted(self
):
227 with self
.assertRaises(UnsortedError
):
228 self
.EXPORTS
+= ["foo.h", "bar.h"]
230 with self
.assertRaises(UnsortedError
):
231 self
.EXPORTS
.foo
= ["foo.h", "bar.h"]
233 with self
.assertRaises(UnsortedError
):
234 self
.EXPORTS
.foo
+= ["foo.h", "bar.h"]
236 def test_reassign(self
):
237 self
.EXPORTS
.foo
= ["foo.h"]
239 with self
.assertRaises(KeyError):
240 self
.EXPORTS
.foo
= ["bar.h"]
243 l
= HierarchicalStringList()
244 l
+= ["root1", "root2", "root3"]
245 l
.child1
+= ["child11", "child12", "child13"]
246 l
.child1
.grandchild1
+= ["grandchild111", "grandchild112"]
247 l
.child1
.grandchild2
+= ["grandchild121", "grandchild122"]
248 l
.child2
.grandchild1
+= ["grandchild211", "grandchild212"]
249 l
.child2
.grandchild1
+= ["grandchild213", "grandchild214"]
251 els
= list((path
, list(seq
)) for path
, seq
in l
.walk())
255 ("", ["root1", "root2", "root3"]),
256 ("child1", ["child11", "child12", "child13"]),
257 ("child1/grandchild1", ["grandchild111", "grandchild112"]),
258 ("child1/grandchild2", ["grandchild121", "grandchild122"]),
260 "child2/grandchild1",
271 def test_merge(self
):
272 l1
= HierarchicalStringList()
273 l1
+= ["root1", "root2", "root3"]
274 l1
.child1
+= ["child11", "child12", "child13"]
275 l1
.child1
.grandchild1
+= ["grandchild111", "grandchild112"]
276 l1
.child1
.grandchild2
+= ["grandchild121", "grandchild122"]
277 l1
.child2
.grandchild1
+= ["grandchild211", "grandchild212"]
278 l1
.child2
.grandchild1
+= ["grandchild213", "grandchild214"]
279 l2
= HierarchicalStringList()
280 l2
.child1
+= ["child14", "child15"]
281 l2
.child1
.grandchild2
+= ["grandchild123"]
282 l2
.child3
+= ["child31", "child32"]
285 els
= list((path
, list(seq
)) for path
, seq
in l1
.walk())
289 ("", ["root1", "root2", "root3"]),
290 ("child1", ["child11", "child12", "child13", "child14", "child15"]),
291 ("child1/grandchild1", ["grandchild111", "grandchild112"]),
293 "child1/grandchild2",
294 ["grandchild121", "grandchild122", "grandchild123"],
297 "child2/grandchild1",
305 ("child3", ["child31", "child32"]),
310 class TestStrictOrderingOnAppendList(unittest
.TestCase
):
312 l
= StrictOrderingOnAppendList()
313 self
.assertEqual(len(l
), 0)
315 l
= StrictOrderingOnAppendList(["a", "b", "c"])
316 self
.assertEqual(len(l
), 3)
318 with self
.assertRaises(UnsortedError
):
319 StrictOrderingOnAppendList(["c", "b", "a"])
321 self
.assertEqual(len(l
), 3)
323 def test_extend(self
):
324 l
= StrictOrderingOnAppendList()
326 self
.assertEqual(len(l
), 2)
327 self
.assertIsInstance(l
, StrictOrderingOnAppendList
)
329 with self
.assertRaises(UnsortedError
):
332 self
.assertEqual(len(l
), 2)
334 def test_slicing(self
):
335 l
= StrictOrderingOnAppendList()
337 self
.assertEqual(len(l
), 2)
338 self
.assertIsInstance(l
, StrictOrderingOnAppendList
)
340 with self
.assertRaises(UnsortedError
):
343 self
.assertEqual(len(l
), 2)
346 l
= StrictOrderingOnAppendList()
348 self
.assertEqual(len(l
), 0)
349 self
.assertEqual(len(l2
), 2)
350 self
.assertIsInstance(l2
, StrictOrderingOnAppendList
)
352 with self
.assertRaises(UnsortedError
):
355 self
.assertEqual(len(l
), 0)
358 l
= StrictOrderingOnAppendList()
360 self
.assertEqual(len(l
), 2)
361 self
.assertIsInstance(l
, StrictOrderingOnAppendList
)
363 with self
.assertRaises(UnsortedError
):
366 self
.assertEqual(len(l
), 2)
368 def test_add_after_iadd(self
):
369 l
= StrictOrderingOnAppendList(["b"])
372 self
.assertEqual(len(l
), 2)
373 self
.assertEqual(len(l2
), 4)
374 self
.assertIsInstance(l2
, StrictOrderingOnAppendList
)
375 with self
.assertRaises(UnsortedError
):
378 self
.assertEqual(len(l
), 2)
380 def test_add_StrictOrderingOnAppendList(self
):
381 l
= StrictOrderingOnAppendList()
384 l2
= StrictOrderingOnAppendList()
385 with self
.assertRaises(UnsortedError
):
387 # Adding a StrictOrderingOnAppendList to another shouldn't throw
391 class TestStrictOrderingOnAppendListWithAction(unittest
.TestCase
):
393 self
.action
= lambda a
: (a
, id(a
))
395 def assertSameList(self
, expected
, actual
):
396 self
.assertEqual(len(expected
), len(actual
))
397 for idx
, item
in enumerate(actual
):
398 self
.assertEqual(item
, expected
[idx
])
401 l
= StrictOrderingOnAppendListWithAction(action
=self
.action
)
402 self
.assertEqual(len(l
), 0)
403 original
= ["a", "b", "c"]
404 l
= StrictOrderingOnAppendListWithAction(["a", "b", "c"], action
=self
.action
)
405 expected
= [self
.action(i
) for i
in original
]
406 self
.assertSameList(expected
, l
)
408 with self
.assertRaises(ValueError):
409 StrictOrderingOnAppendListWithAction("abc", action
=self
.action
)
411 with self
.assertRaises(ValueError):
412 StrictOrderingOnAppendListWithAction()
414 def test_extend(self
):
415 l
= StrictOrderingOnAppendListWithAction(action
=self
.action
)
416 original
= ["a", "b"]
418 expected
= [self
.action(i
) for i
in original
]
419 self
.assertSameList(expected
, l
)
421 with self
.assertRaises(ValueError):
424 def test_slicing(self
):
425 l
= StrictOrderingOnAppendListWithAction(action
=self
.action
)
426 original
= ["a", "b"]
428 expected
= [self
.action(i
) for i
in original
]
429 self
.assertSameList(expected
, l
)
431 with self
.assertRaises(ValueError):
435 l
= StrictOrderingOnAppendListWithAction(action
=self
.action
)
436 original
= ["a", "b"]
438 expected
= [self
.action(i
) for i
in original
]
439 self
.assertSameList(expected
, l2
)
441 with self
.assertRaises(ValueError):
445 l
= StrictOrderingOnAppendListWithAction(action
=self
.action
)
446 original
= ["a", "b"]
448 expected
= [self
.action(i
) for i
in original
]
449 self
.assertSameList(expected
, l
)
451 with self
.assertRaises(ValueError):
455 class TestStrictOrderingOnAppendListWithFlagsFactory(unittest
.TestCase
):
456 def test_strict_ordering_on_append_list_with_flags_factory(self
):
457 cls
= StrictOrderingOnAppendListWithFlagsFactory(
467 with self
.assertRaises(Exception):
470 with self
.assertRaises(Exception):
473 self
.assertEqual(l
["a"].foo
, False)
475 self
.assertEqual(l
["a"].foo
, True)
477 with self
.assertRaises(TypeError):
480 self
.assertEqual(l
["a"].bar
, 0)
482 self
.assertEqual(l
["a"].bar
, 42)
485 self
.assertEqual(l
["b"].foo
, True)
487 with self
.assertRaises(AttributeError):
490 l
["b"].update(foo
=False, bar
=12)
491 self
.assertEqual(l
["b"].foo
, False)
492 self
.assertEqual(l
["b"].bar
, 12)
494 with self
.assertRaises(AttributeError):
497 def test_strict_ordering_on_append_list_with_flags_factory_extend(self
):
498 FooList
= StrictOrderingOnAppendListWithFlagsFactory(
499 {"foo": bool, "bar": six
.text_type
}
501 foo
= FooList(["a", "b", "c"])
505 # Don't allow extending lists with different flag definitions.
506 BarList
= StrictOrderingOnAppendListWithFlagsFactory(
507 {"foo": six
.text_type
, "baz": bool}
509 bar
= BarList(["d", "e", "f"])
512 with self
.assertRaises(ValueError):
514 with self
.assertRaises(ValueError):
517 # It's not obvious what to do with duplicate list items with possibly
518 # different flag values, so don't allow that case.
519 with self
.assertRaises(ValueError):
522 def assertExtended(l
):
523 self
.assertEqual(len(l
), 6)
524 self
.assertEqual(l
["a"].foo
, True)
525 self
.assertEqual(l
["b"].bar
, "bar")
526 self
.assertTrue("c" in l
)
527 self
.assertEqual(l
["d"].foo
, True)
528 self
.assertEqual(l
["e"].bar
, "bar")
529 self
.assertTrue("f" in l
)
532 zot
= FooList(["d", "e", "f"])
539 zot
= FooList(["d", "e", "f"])
542 assertExtended(foo
+ zot
)
543 assertExtended(zot
+ foo
)
551 self
.assertEqual(len(foo
), 3)
556 class TestMemoize(unittest
.TestCase
):
557 def test_memoize(self
):
565 self
.assertEqual(self
._count
, 0)
566 self
.assertEqual(wrapped(1, 1), 2)
567 self
.assertEqual(self
._count
, 1)
568 self
.assertEqual(wrapped(1, 1), 2)
569 self
.assertEqual(self
._count
, 1)
570 self
.assertEqual(wrapped(2, 1), 3)
571 self
.assertEqual(self
._count
, 2)
572 self
.assertEqual(wrapped(1, 2), 3)
573 self
.assertEqual(self
._count
, 3)
574 self
.assertEqual(wrapped(1, 2), 3)
575 self
.assertEqual(self
._count
, 3)
576 self
.assertEqual(wrapped(1, 1), 2)
577 self
.assertEqual(self
._count
, 3)
579 def test_memoize_method(self
):
585 def wrapped(self
, a
, b
):
590 refcount
= sys
.getrefcount(instance
)
591 self
.assertEqual(instance
._count
, 0)
592 self
.assertEqual(instance
.wrapped(1, 1), 2)
593 self
.assertEqual(instance
._count
, 1)
594 self
.assertEqual(instance
.wrapped(1, 1), 2)
595 self
.assertEqual(instance
._count
, 1)
596 self
.assertEqual(instance
.wrapped(2, 1), 3)
597 self
.assertEqual(instance
._count
, 2)
598 self
.assertEqual(instance
.wrapped(1, 2), 3)
599 self
.assertEqual(instance
._count
, 3)
600 self
.assertEqual(instance
.wrapped(1, 2), 3)
601 self
.assertEqual(instance
._count
, 3)
602 self
.assertEqual(instance
.wrapped(1, 1), 2)
603 self
.assertEqual(instance
._count
, 3)
605 # Memoization of methods is expected to not keep references to
606 # instances, so the refcount shouldn't have changed after executing the
608 self
.assertEqual(refcount
, sys
.getrefcount(instance
))
610 def test_memoized_property(self
):
621 self
.assertEqual(instance
._count
, 0)
622 self
.assertEqual(instance
.wrapped
, 42)
623 self
.assertEqual(instance
._count
, 1)
624 self
.assertEqual(instance
.wrapped
, 42)
625 self
.assertEqual(instance
._count
, 1)
628 class TestTypedList(unittest
.TestCase
):
632 self
.assertEqual(len(l
), 0)
635 self
.assertEqual(len(l
), 3)
637 with self
.assertRaises(ValueError):
640 def test_extend(self
):
644 self
.assertEqual(len(l
), 2)
645 self
.assertIsInstance(l
, cls
)
647 with self
.assertRaises(ValueError):
650 self
.assertEqual(len(l
), 2)
652 def test_slicing(self
):
656 self
.assertEqual(len(l
), 2)
657 self
.assertIsInstance(l
, cls
)
659 with self
.assertRaises(ValueError):
662 self
.assertEqual(len(l
), 2)
668 self
.assertEqual(len(l
), 0)
669 self
.assertEqual(len(l2
), 2)
670 self
.assertIsInstance(l2
, cls
)
672 with self
.assertRaises(ValueError):
675 self
.assertEqual(len(l
), 0)
681 self
.assertEqual(len(l
), 2)
682 self
.assertIsInstance(l
, cls
)
684 with self
.assertRaises(ValueError):
687 self
.assertEqual(len(l
), 2)
689 def test_add_coercion(self
):
693 def __init__(self
, obj
):
699 self
.assertEqual(len(objs
), 2)
700 self
.assertEqual(type(l
[0]), Foo
)
701 self
.assertEqual(type(l
[1]), Foo
)
703 # Adding a TypedList to a TypedList shouldn't trigger coercion again
706 self
.assertEqual(len(objs
), 2)
707 self
.assertEqual(type(l2
[0]), Foo
)
708 self
.assertEqual(type(l2
[1]), Foo
)
710 # Adding a TypedList to a TypedList shouldn't even trigger the code
711 # that does coercion at all.
713 list.__setitem
__(l
, slice(0, -1), [1, 2])
715 self
.assertEqual(len(objs
), 2)
716 self
.assertEqual(type(l2
[0]), int)
717 self
.assertEqual(type(l2
[1]), int)
719 def test_memoized(self
):
721 cls2
= TypedList(str)
722 self
.assertEqual(TypedList(int), cls
)
723 self
.assertNotEqual(cls
, cls2
)
726 class TypedTestStrictOrderingOnAppendList(unittest
.TestCase
):
728 class Unicode(six
.text_type
):
729 def __new__(cls
, other
):
730 if not isinstance(other
, six
.text_type
):
732 return six
.text_type
.__new
__(cls
, other
)
734 cls
= TypedList(Unicode
, StrictOrderingOnAppendList
)
736 self
.assertEqual(len(l
), 0)
738 l
= cls(["a", "b", "c"])
739 self
.assertEqual(len(l
), 3)
741 with self
.assertRaises(UnsortedError
):
744 with self
.assertRaises(ValueError):
747 self
.assertEqual(len(l
), 3)
750 class TestTypedNamedTuple(unittest
.TestCase
):
751 def test_simple(self
):
752 FooBar
= TypedNamedTuple("FooBar", [("foo", six
.text_type
), ("bar", int)])
754 t
= FooBar(foo
="foo", bar
=2)
755 self
.assertEqual(type(t
), FooBar
)
756 self
.assertEqual(t
.foo
, "foo")
757 self
.assertEqual(t
.bar
, 2)
758 self
.assertEqual(t
[0], "foo")
759 self
.assertEqual(t
[1], 2)
763 with self
.assertRaises(TypeError):
764 FooBar("foo", "not integer")
765 with self
.assertRaises(TypeError):
768 # Passing a tuple as the first argument is the same as passing multiple
772 self
.assertEqual(type(t2
), FooBar
)
773 self
.assertEqual(FooBar(t1
), FooBar("foo", 3))
776 class TestGroupUnifiedFiles(unittest
.TestCase
):
777 FILES
= ["%s.cpp" % letter
for letter
in string
.ascii_lowercase
]
779 def test_multiple_files(self
):
780 mapping
= list(group_unified_files(self
.FILES
, "Unified", "cpp", 5))
782 def check_mapping(index
, expected_num_source_files
):
783 (unified_file
, source_files
) = mapping
[index
]
785 self
.assertEqual(unified_file
, "Unified%d.cpp" % index
)
786 self
.assertEqual(len(source_files
), expected_num_source_files
)
788 all_files
= list(itertools
.chain(*[files
for (_
, files
) in mapping
]))
789 self
.assertEqual(len(all_files
), len(self
.FILES
))
790 self
.assertEqual(set(all_files
), set(self
.FILES
))
792 expected_amounts
= [5, 5, 5, 5, 5, 1]
793 for i
, amount
in enumerate(expected_amounts
):
794 check_mapping(i
, amount
)
797 class TestMisc(unittest
.TestCase
):
799 self
.assertEqual(list(pair([1, 2, 3, 4, 5, 6])), [(1, 2), (3, 4), (5, 6)])
802 list(pair([1, 2, 3, 4, 5, 6, 7])), [(1, 2), (3, 4), (5, 6), (7, None)]
805 def test_expand_variables(self
):
806 self
.assertEqual(expand_variables("$(var)", {"var": "value"}), "value")
809 expand_variables("$(a) and $(b)", {"a": "1", "b": "2"}), "1 and 2"
813 expand_variables("$(a) and $(undefined)", {"a": "1", "b": "2"}), "1 and "
818 "before $(string) between $(list) after",
819 {"string": "abc", "list": ["a", "b", "c"]},
821 "before abc between a b c after",
825 class TestEnumString(unittest
.TestCase
):
826 def test_string(self
):
827 class CompilerType(EnumString
):
828 POSSIBLE_VALUES
= ("gcc", "clang", "clang-cl")
830 type = CompilerType("gcc")
831 self
.assertEqual(type, "gcc")
832 self
.assertNotEqual(type, "clang")
833 self
.assertNotEqual(type, "clang-cl")
834 self
.assertIn(type, ("gcc", "clang-cl"))
835 self
.assertNotIn(type, ("clang", "clang-cl"))
837 with self
.assertRaises(EnumStringComparisonError
):
838 self
.assertEqual(type, "foo")
840 with self
.assertRaises(EnumStringComparisonError
):
841 self
.assertNotEqual(type, "foo")
843 with self
.assertRaises(EnumStringComparisonError
):
844 self
.assertIn(type, ("foo", "gcc"))
846 with self
.assertRaises(ValueError):
847 type = CompilerType("foo")
850 class TestHexDump(unittest
.TestCase
):
851 @unittest.skipUnless(six
.PY3
, "requires Python 3")
852 def test_hexdump(self
):
854 hexdump("abcdef123💩ZYXWVU".encode("utf-8")),
856 "00 61 62 63 64 65 66 31 32 33 f0 9f 92 a9 5a 59 58 |abcdef123....ZYX|\n",
857 "10 57 56 55 |WVU |\n",
862 def test_read_only_dict():
863 d
= ReadOnlyDict(foo
="bar")
864 with pytest
.raises(Exception):
867 with pytest
.raises(Exception):
868 d
.update({"foo": "baz"})
870 with pytest
.raises(Exception):
873 # ensure copy still works
876 # TODO Returning a dict here feels like a bug, but there are places in-tree
877 # relying on this behaviour.
878 assert isinstance(d_copy
, dict)
880 d_copy
= copy
.copy(d
)
882 assert isinstance(d_copy
, ReadOnlyDict
)
884 d_copy
= copy
.deepcopy(d
)
886 assert isinstance(d_copy
, ReadOnlyDict
)
889 if __name__
== "__main__":