Coverage for tests/test_sequin.py: 100.000%

56 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-07-14 11:39 +0200

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

2# 

3# SPDX-License-Identifier: MIT 

4 

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

6 

7import collections 

8 

9import pytest 

10import sequin 

11 

12class 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 

38class 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)