Coverage for tests/test_000_frigid/test_300_namespaces.py: 100%

101 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-01-24 04:09 +0000

1# vim: set filetype=python fileencoding=utf-8: 

2# -*- coding: utf-8 -*- 

3 

4#============================================================================# 

5# # 

6# Licensed under the Apache License, Version 2.0 (the "License"); # 

7# you may not use this file except in compliance with the License. # 

8# You may obtain a copy of the License at # 

9# # 

10# http://www.apache.org/licenses/LICENSE-2.0 # 

11# # 

12# Unless required by applicable law or agreed to in writing, software # 

13# distributed under the License is distributed on an "AS IS" BASIS, # 

14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

15# See the License for the specific language governing permissions and # 

16# limitations under the License. # 

17# # 

18#============================================================================# 

19 

20 

21''' Assert correct function of namespaces. ''' 

22 

23# mypy: ignore-errors 

24# pylint: disable=attribute-defined-outside-init 

25# pylint: disable=invalid-name,magic-value-comparison,protected-access 

26 

27 

28import pytest 

29 

30from itertools import product 

31 

32from . import ( 

33 MODULES_QNAMES, 

34 PACKAGE_NAME, 

35 cache_import_module, 

36) 

37 

38 

39THESE_MODULE_QNAMES = tuple( 

40 name for name in MODULES_QNAMES if name.endswith( '.namespaces' ) ) 

41THESE_CLASSES_NAMES = ( 'Namespace', ) 

42 

43base = cache_import_module( f"{PACKAGE_NAME}.__" ) 

44exceptions = cache_import_module( f"{PACKAGE_NAME}.exceptions" ) 

45 

46 

47@pytest.mark.parametrize( 

48 'module_qname, class_name', 

49 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

50) 

51def test_100_instantiation( module_qname, class_name ): 

52 ''' Class instantiates with various input types. ''' 

53 module = cache_import_module( module_qname ) 

54 Namespace = getattr( module, class_name ) 

55 ns1 = Namespace( ) 

56 assert isinstance( ns1, Namespace ) 

57 ns2 = Namespace( 

58 ( ( 'foo', 1 ), ( 'bar', 2 ) ), { 'unicorn': True }, orb = False ) 

59 assert isinstance( ns2, Namespace ) 

60 assert 1 == ns2.foo 

61 assert 2 == ns2.bar 

62 assert ns2.unicorn 

63 assert not ns2.orb 

64 assert ( 'foo', 'bar', 'unicorn', 'orb' ) == tuple( ns2.__dict__.keys( ) ) 

65 assert ( 1, 2, True, False ) == tuple( ns2.__dict__.values( ) ) 

66 

67 

68@pytest.mark.parametrize( 

69 'module_qname, class_name', 

70 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

71) 

72def test_101_immutability( module_qname, class_name ): 

73 ''' Namespace prevents attribute modification after initialization. ''' 

74 module = cache_import_module( module_qname ) 

75 Namespace = getattr( module, class_name ) 

76 ns1 = Namespace( attr = 42 ) 

77 with pytest.raises( exceptions.AttributeImmutabilityError ): 

78 ns1.attr = -1 

79 assert 42 == ns1.attr 

80 with pytest.raises( exceptions.AttributeImmutabilityError ): 

81 del ns1.attr 

82 assert 42 == ns1.attr 

83 with pytest.raises( exceptions.AttributeImmutabilityError ): 

84 ns1.new_attr = 'test' 

85 ns2 = Namespace( ) 

86 with pytest.raises( exceptions.AttributeImmutabilityError ): 

87 ns2.attr = 42 

88 

89 

90@pytest.mark.parametrize( 

91 'module_qname, class_name', 

92 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

93) 

94def test_102_string_representation( module_qname, class_name ): 

95 ''' Namespace has expected string representations. ''' 

96 module = cache_import_module( module_qname ) 

97 factory = getattr( module, class_name ) 

98 ns1 = factory( ) 

99 assert base.calculate_fqname( ns1 ) in repr( ns1 ) 

100 assert repr( ns1 ).endswith( '( )' ) 

101 ns2 = factory( a = 1, b = 2 ) 

102 assert base.calculate_fqname( ns2 ) in repr( ns2 ) 

103 assert 'a = 1, b = 2' in repr( ns2 ) 

104 

105 

106@pytest.mark.parametrize( 

107 'module_qname, class_name', 

108 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

109) 

110def test_105_namespace_equality( module_qname, class_name ): 

111 ''' Namespace compares properly with other namespaces. ''' 

112 from types import SimpleNamespace 

113 module = cache_import_module( module_qname ) 

114 factory = getattr( module, class_name ) 

115 ns1 = factory( foo = 1, bar = 2 ) 

116 ns2 = factory( foo = 1, bar = 2 ) 

117 assert ns1 == ns2 

118 assert ns2 == ns1 

119 ns3 = SimpleNamespace( foo = 1, bar = 2 ) 

120 assert ns1 == ns3 

121 assert ns3 == ns1 

122 assert not ( ns1 == -1 ) # pylint: disable=superfluous-parens 

123 assert ns1 != -1 

124 assert ns1 != ( ) 

125 ns4 = factory( foo = 1, bar = 3 ) 

126 assert ns1 != ns4 

127 assert ns4 != ns1 

128 

129 

130@pytest.mark.parametrize( 

131 'module_qname, class_name', 

132 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

133) 

134def test_106_namespace_initialization_validation( module_qname, class_name ): 

135 ''' Namespace properly handles various initialization inputs. ''' 

136 module = cache_import_module( module_qname ) 

137 factory = getattr( module, class_name ) 

138 ns1 = factory( { 'a': 1, 'b': 2 } ) 

139 assert 1 == ns1.a 

140 assert 2 == ns1.b 

141 ns2 = factory( [ ( 'c', 3 ), ( 'd', 4 ) ] ) 

142 assert 3 == ns2.c 

143 assert 4 == ns2.d 

144 ns3 = factory( e = 5, f = 6 ) 

145 assert 5 == ns3.e 

146 assert 6 == ns3.f 

147 ns4 = factory( { 'g': 7 }, [ ( 'h', 8 ) ], i = 9 ) 

148 assert 7 == ns4.g 

149 assert 8 == ns4.h 

150 assert 9 == ns4.i 

151 

152 

153@pytest.mark.parametrize( 

154 'module_qname, class_name', 

155 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

156) 

157def test_900_docstring_sanity( module_qname, class_name ): 

158 ''' Class has valid docstring. ''' 

159 module = cache_import_module( module_qname ) 

160 Object = getattr( module, class_name ) 

161 assert hasattr( Object, '__doc__' ) 

162 assert isinstance( Object.__doc__, str ) 

163 assert Object.__doc__ 

164 

165 

166@pytest.mark.parametrize( 

167 'module_qname, class_name', 

168 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

169) 

170def test_901_docstring_describes_namespace( module_qname, class_name ): 

171 ''' Class docstring describes namespace. ''' 

172 module = cache_import_module( module_qname ) 

173 Object = getattr( module, class_name ) 

174 fragment = base.generate_docstring( 'description of namespace' ) 

175 assert fragment in Object.__doc__ 

176 

177 

178@pytest.mark.parametrize( 

179 'module_qname, class_name', 

180 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

181) 

182def test_902_docstring_mentions_immutability( module_qname, class_name ): 

183 ''' Class docstring mentions immutability. ''' 

184 module = cache_import_module( module_qname ) 

185 Object = getattr( module, class_name ) 

186 fragment = base.generate_docstring( 'instance attributes immutability' ) 

187 assert fragment in Object.__doc__