Coverage for tests/test_sequin.py: 100.000%

1# SPDX-FileCopyrightText: 2024 Marco Ricci <m@the13thletter.info>

2#

3# SPDX-License-Identifier: MIT

4

5"""Test sequin.Sequin."""

6

7 import collections

8

9 import pytest

10 import sequin

11

12 class TestStaticFunctionality:

13

14 @pytest.mark.parametrize(['sequence', 'base', 'expected'], [

15 ([1, 2, 3, 4, 5, 6], 10, 123456),

16 ([1, 2, 3, 4, 5, 6], 100, 10203040506),

17 ([0, 0, 1, 4, 9, 7], 10, 1497),

18 ([1, 0, 0, 1, 0, 0, 0, 0], 2, 144),

19 ([1, 7, 5, 5], 8, 0o1755),

20 ])

21 def test_200_big_endian_number(self, sequence, base, expected):

22 assert (

23 sequin.Sequin._big_endian_number(sequence, base=base)

24 ) == expected

25

26 @pytest.mark.parametrize(

27 ['exc_type', 'exc_pattern', 'sequence' , 'base'], [

28 (ValueError, 'invalid base 3 digit:', [-1], 3),

29 (ValueError, 'invalid base:', [0], 1),

30 (TypeError, 'not an integer:', [0.0, 1.0, 0.0, 1.0], 2),

31 ]

32 )

33 def test_300_big_endian_number_exceptions(self, exc_type, exc_pattern,

34 sequence, base):

35 with pytest.raises(exc_type, match=exc_pattern):

36 sequin.Sequin._big_endian_number(sequence, base=base)

37

38 class TestSequin:

39

40 @pytest.mark.parametrize(['sequence', 'is_bitstring', 'expected'], [

41 ([1, 0, 0, 1, 0, 1], False, [0, 0, 0, 0, 0, 0, 0, 1,

42 0, 0, 0, 0, 0, 0, 0, 0,

43 0, 0, 0, 0, 0, 0, 0, 0,

44 0, 0, 0, 0, 0, 0, 0, 1,

45 0, 0, 0, 0, 0, 0, 0, 0,

46 0, 0, 0, 0, 0, 0, 0, 1]),

47 ([1, 0, 0, 1, 0, 1], True, [1, 0, 0, 1, 0, 1]),

48 (b'OK', False, [0, 1, 0, 0, 1, 1, 1, 1,

49 0, 1, 0, 0, 1, 0, 1, 1]),

50 ('OK', False, [0, 1, 0, 0, 1, 1, 1, 1,

51 0, 1, 0, 0, 1, 0, 1, 1]),

52 ])

53 def test_200_constructor(self, sequence, is_bitstring, expected):

54 seq = sequin.Sequin(sequence, is_bitstring=is_bitstring)

55 assert seq.bases == {2: collections.deque(expected)}

56

57 def test_201_generating(self):

58 seq = sequin.Sequin([1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1],

59 is_bitstring=True)

60 assert seq.generate(1) == 0

61 assert seq.generate(5) == 3

62 assert seq.generate(5) == 3

63 assert seq.generate(5) == 1

64 with pytest.raises(sequin.SequinExhaustedError):

65 seq.generate(5)

66 with pytest.raises(sequin.SequinExhaustedError):

67 seq.generate(1)

68 seq = sequin.Sequin([1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1],

69 is_bitstring=True)

70 with pytest.raises(ValueError, match='invalid target range'):

71 seq.generate(0)

72

73 def test_210_internal_generating(self):

74 seq = sequin.Sequin([1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1],

75 is_bitstring=True)

76 assert seq._generate_inner(5) == 3

77 assert seq._generate_inner(5) == 3

78 assert seq._generate_inner(5) == 1

79 assert seq._generate_inner(5) == 5

80 assert seq._generate_inner(1) == 0

81 seq = sequin.Sequin([1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1],

82 is_bitstring=True)

83 assert seq._generate_inner(1) == 0

84 with pytest.raises(ValueError, match='invalid target range'):

85 seq._generate_inner(0)

86 with pytest.raises(ValueError, match='invalid base:'):

87 seq._generate_inner(16, base=1)

88

89 def test_211_shifting(self):

90 seq = sequin.Sequin([1, 0, 1, 0, 0, 1, 0, 0, 0, 1], is_bitstring=True)

91 assert seq.bases == {2: collections.deque([1, 0, 1, 0, 0, 1, 0, 0, 0, 1])}

92 #

93 assert seq._all_or_nothing_shift(3) == (1, 0, 1)

94 assert seq._all_or_nothing_shift(3) == (0, 0, 1)

95 assert seq.bases[2] == collections.deque([0, 0, 0, 1])

96 #

97 assert seq._all_or_nothing_shift(5) == ()

98 assert seq.bases[2] == collections.deque([0, 0, 0, 1])

99 #

100 assert seq._all_or_nothing_shift(4), (0, 0, 0, 1)

101 assert 2 not in seq.bases

102

103 @pytest.mark.parametrize(

104 ['sequence', 'is_bitstring', 'exc_type', 'exc_pattern'],

105 [

106 ([0, 1, 2, 3, 4, 5, 6, 7], True,

107 ValueError, 'sequence item out of range'),

108 (u'こんにちは。', False,

109 ValueError, 'sequence item out of range'),

110 ]

111 )

112 def test_300_constructor_exceptions(self, sequence, is_bitstring,

113 exc_type, exc_pattern):

114 with pytest.raises(exc_type, match=exc_pattern):

115 sequin.Sequin(sequence, is_bitstring=is_bitstring)