Coverage for tests/test_000_accretive/test_400_modules.py: 100%

122 statements  

« prev     ^ index     » next       coverage.py v7.5.4, created at 2024-07-06 17:17 +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 modules. ''' 

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 CONCEALMENT_PACKAGES_NAMES, 

34 MODULES_QNAMES, 

35 PACKAGE_NAME, 

36 PROTECTION_PACKAGES_NAMES, 

37 cache_import_module, 

38) 

39 

40 

41THESE_MODULE_QNAMES = tuple( 

42 name for name in MODULES_QNAMES if name.endswith( '.modules' ) ) 

43THESE_CONCEALMENT_MODULE_QNAMES = tuple( 

44 name for name in THESE_MODULE_QNAMES 

45 if name.startswith( CONCEALMENT_PACKAGES_NAMES ) ) 

46THESE_NONCONCEALMENT_MODULE_QNAMES = tuple( 

47 name for name in THESE_MODULE_QNAMES 

48 if not name.startswith( CONCEALMENT_PACKAGES_NAMES ) ) 

49THESE_PROTECTION_MODULE_QNAMES = tuple( 

50 name for name in THESE_MODULE_QNAMES 

51 if name.startswith( PROTECTION_PACKAGES_NAMES ) ) 

52THESE_NONPROTECTION_MODULE_QNAMES = tuple( 

53 name for name in THESE_MODULE_QNAMES 

54 if not name.startswith( PROTECTION_PACKAGES_NAMES ) ) 

55THESE_CLASSES_NAMES = ( 'Module', ) 

56 

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

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

59 

60 

61@pytest.mark.parametrize( 

62 'module_qname, class_name', 

63 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

64) 

65def test_100_instantiation( module_qname, class_name ): 

66 ''' Class instantiates. ''' 

67 module = cache_import_module( module_qname ) 

68 Module = getattr( module, class_name ) 

69 obj = Module( 'foo' ) 

70 assert isinstance( obj, Module ) 

71 assert 'foo' == obj.__name__ 

72 

73 

74@pytest.mark.parametrize( 

75 'module_qname, class_name', 

76 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

77) 

78def test_101_accretion( module_qname, class_name ): 

79 ''' Module accretes attributes. ''' 

80 module = cache_import_module( module_qname ) 

81 Module = getattr( module, class_name ) 

82 obj = Module( 'foo' ) 

83 obj.attr = 42 

84 with pytest.raises( exceptions.IndelibleAttributeError ): 

85 obj.attr = -1 

86 assert 42 == obj.attr 

87 with pytest.raises( exceptions.IndelibleAttributeError ): 

88 del obj.attr 

89 assert 42 == obj.attr 

90 

91 

92@pytest.mark.parametrize( 

93 'module_qname, class_name', 

94 product( THESE_CONCEALMENT_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

95) 

96def test_110_attribute_concealment( module_qname, class_name ): 

97 ''' Module conceals attributes. ''' 

98 module = cache_import_module( module_qname ) 

99 Module = getattr( module, class_name ) 

100 

101 class Concealer( Module ): 

102 ''' test ''' 

103 _attribute_visibility_includes_ = frozenset( ( '_private', ) ) 

104 

105 obj = Concealer( 'foo' ) 

106 assert not dir( obj ) 

107 obj.public = 42 

108 assert 'public' in dir( obj ) 

109 obj._nonpublic = 3.1415926535 

110 assert '_nonpublic' not in dir( obj ) 

111 assert '_private' not in dir( obj ) 

112 obj._private = 'foo' 

113 assert '_private' in dir( obj ) 

114 

115 

116@pytest.mark.parametrize( 

117 'module_qname, class_name', 

118 product( THESE_NONCONCEALMENT_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

119) 

120def test_111_attribute_nonconcealment( module_qname, class_name ): 

121 ''' Module does not conceal attributes. ''' 

122 module = cache_import_module( module_qname ) 

123 Module = getattr( module, class_name ) 

124 

125 class Concealer( Module ): 

126 ''' test ''' 

127 

128 obj = Concealer( 'foo' ) 

129 assert '_attribute_visibility_includes_' not in dir( obj ) 

130 obj._attribute_visibility_includes_ = frozenset( ( '_private', ) ) 

131 assert '_attribute_visibility_includes_' in dir( obj ) 

132 obj.public = 42 

133 assert 'public' in dir( obj ) 

134 obj._nonpublic = 3.1415926535 

135 assert '_nonpublic' in dir( obj ) 

136 assert '_private' not in dir( obj ) 

137 obj._private = 'foo' 

138 assert '_private' in dir( obj ) 

139 

140 

141@pytest.mark.parametrize( 

142 'module_qname, class_name', 

143 product( THESE_PROTECTION_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

144) 

145def test_150_class_attribute_protection( module_qname, class_name ): 

146 ''' Class attributes are protected. ''' 

147 module = cache_import_module( module_qname ) 

148 Object = getattr( module, class_name ) 

149 with pytest.raises( exceptions.IndelibleAttributeError ): 

150 Object.__setattr__ = None 

151 with pytest.raises( exceptions.IndelibleAttributeError ): 

152 del Object.__setattr__ 

153 Object.foo = 42 

154 with pytest.raises( exceptions.IndelibleAttributeError ): 

155 Object.foo = -1 

156 with pytest.raises( exceptions.IndelibleAttributeError ): 

157 del Object.foo 

158 # Cleanup. 

159 type.__delattr__( Object, 'foo' ) 

160 

161 

162@pytest.mark.parametrize( 

163 'module_qname, class_name', 

164 product( THESE_NONPROTECTION_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

165) 

166def test_151_class_attribute_nonprotection( module_qname, class_name ): 

167 ''' Class attributes are not protected. ''' 

168 module = cache_import_module( module_qname ) 

169 Object = getattr( module, class_name ) 

170 Object.foo = 42 

171 assert 42 == Object.foo 

172 Object.foo = -1 

173 assert -1 == Object.foo 

174 del Object.foo 

175 assert not hasattr( Object, 'foo' ) 

176 

177 

178@pytest.mark.parametrize( 

179 'module_qname, class_name', 

180 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

181) 

182def test_900_docstring_sanity( module_qname, class_name ): 

183 ''' Class has valid docstring. ''' 

184 module = cache_import_module( module_qname ) 

185 Object = getattr( module, class_name ) 

186 assert hasattr( Object, '__doc__' ) 

187 assert isinstance( Object.__doc__, str ) 

188 assert Object.__doc__ 

189 

190 

191@pytest.mark.parametrize( 

192 'module_qname, class_name', 

193 product( THESE_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

194) 

195def test_902_docstring_mentions_accretion( module_qname, class_name ): 

196 ''' Class docstring mentions accretion. ''' 

197 module = cache_import_module( module_qname ) 

198 Object = getattr( module, class_name ) 

199 fragment = base.generate_docstring( 'module attributes accretion' ) 

200 assert fragment in Object.__doc__ 

201 

202 

203@pytest.mark.parametrize( 

204 'module_qname, class_name', 

205 product( THESE_CONCEALMENT_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

206) 

207def test_910_docstring_mentions_concealment( module_qname, class_name ): 

208 ''' Class docstring mentions concealment. ''' 

209 module = cache_import_module( module_qname ) 

210 Object = getattr( module, class_name ) 

211 fragment = base.generate_docstring( 'module attributes concealment' ) 

212 assert fragment in Object.__doc__ 

213 

214 

215@pytest.mark.parametrize( 

216 'module_qname, class_name', 

217 product( THESE_NONCONCEALMENT_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

218) 

219def test_911_docstring_not_mentions_concealment( module_qname, class_name ): 

220 ''' Class docstring does not mention concealment. ''' 

221 module = cache_import_module( module_qname ) 

222 Object = getattr( module, class_name ) 

223 fragment = base.generate_docstring( 'module attributes concealment' ) 

224 assert fragment not in Object.__doc__ 

225 

226 

227@pytest.mark.parametrize( 

228 'module_qname, class_name', 

229 product( THESE_PROTECTION_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

230) 

231def test_930_docstring_mentions_protection( module_qname, class_name ): 

232 ''' Class docstring mentions protection. ''' 

233 module = cache_import_module( module_qname ) 

234 Object = getattr( module, class_name ) 

235 fragment = base.generate_docstring( 'protection of module class' ) 

236 assert fragment in Object.__doc__ 

237 

238 

239@pytest.mark.parametrize( 

240 'module_qname, class_name', 

241 product( THESE_NONPROTECTION_MODULE_QNAMES, THESE_CLASSES_NAMES ) 

242) 

243def test_931_docstring_not_mentions_protection( module_qname, class_name ): 

244 ''' Class docstring does not mention protection. ''' 

245 module = cache_import_module( module_qname ) 

246 Object = getattr( module, class_name ) 

247 fragment = base.generate_docstring( 'protection of module class' ) 

248 assert fragment not in Object.__doc__