Ticket #34719: tests_abcmodel_bug.py

File tests_abcmodel_bug.py, 4.9 KB (added by piscvau, 16 months ago)

unittest test file to reproduce

Line 
1#!/usr/bin/env python
2# coding:utf-8
3"""
4This file is part of the Ludd21 proprietary software
5License
6=======
7
8Copyright (C) <2019> <Odile Troulet-Lambert.tex@orange.fr>
9
10this programm is proprietary software
11
12
13
14Module purpose
15==============
16tests for the module fabric_elements
17because of the import of app_accounts.models and Fabric Type which inherits from
18django models this test module requires django to be configured.
19set environment variable $TEST_MODULE_MODELS to fabric_elements so as not to load all other model modules
20
21Implements
22==========
23
24
25Documentation
26=============
27
28
29Usage
30=====
31
32
33@author: Odile Troulet-Lambert
34@copyright: Odile Troulet-Lambert
35
36"""
37import unittest
38import os
39from unittest.mock import patch
40from abc import abstractmethod, ABCMeta
41
42from django.db.models.base import ModelBase
43import django.db.models as models
44from django.apps.registry import Apps
45
46
47class AbstractModelMeta(ABCMeta, type(models.Model)):
48 """ a Django model and python abstract class"""
49
50 def __new__(cls, name, bases, attrs, **kwargs):
51
52 clas = super().__new__(cls, name, bases, attrs, **kwargs)
53 return clas
54
55
56class Test_AbstractImplementation (unittest.TestCase):
57
58 @classmethod
59 def setUpClass(cls):
60 os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoLudd21.settings'
61 cls.patcher = patch.object(Apps, 'check_apps_ready')
62 cls.patcher.start()
63
64 class AbsImplementation (models.Model,
65 metaclass=AbstractModelMeta):
66 class Meta:
67 app_label = 'fakeapp'
68 abstract = True
69
70 field1 = models.CharField(
71 max_length=20)
72 field2 = models.IntegerField(
73 default=5)
74
75 @staticmethod
76 def change_field():
77 return 10
78
79 @abstractmethod
80 def absmethod(self):
81 pass
82
83 def __init_subclass__(cls, **kwargs):
84 machine = kwargs.pop('machine', None)
85 if not machine:
86 raise ValueError('implementation must have a machine attribute')
87 setattr(cls, 'machine', machine)
88 field1 = models.CharField(
89 max_length=cls.change_field(),
90 )
91 ModelBase.add_to_class(cls, 'field1', field1)
92
93 cls.absimp = AbsImplementation
94
95 def test(self):
96 class Imp (self.absimp,
97 machine='machine'):
98
99 class Meta:
100 app_label = 'fakeapp'
101 abstract = False
102
103 def absmethod(self):
104 pass
105
106 self.assertTrue(issubclass(Imp, models.Model))
107 self.assertTrue(issubclass(Imp, self.absimp))
108
109 self.assertEqual(Imp.machine, 'machine')
110 field1 = Imp._meta.get_field('field1')
111 field2 = Imp._meta.get_field('field2')
112 self.assertEqual(field1.max_length, 10)
113 self.assertEqual(field2.default, 5)
114
115 @classmethod
116 def tearDownClass(cls):
117 cls.patcher.stop()
118
119
120class Test_ConcreteImplementation (unittest.TestCase):
121
122 @classmethod
123 def setUpClass(cls):
124 os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoLudd21.settings'
125 cls.patcher = patch.object(Apps, 'check_apps_ready')
126 cls.patcher.start()
127
128 class Implementation (models.Model,
129 metaclass=AbstractModelMeta):
130 class Meta:
131 app_label = 'fakeapp'
132 abstract = False
133
134 field1 = models.CharField(
135 max_length=20)
136 field2 = models.IntegerField(
137 default=5)
138
139 @staticmethod
140 def change_field():
141 return 10
142
143 @abstractmethod
144 def absmethod(self):
145 pass
146
147 def __init_subclass__(cls, **kwargs):
148 machine = kwargs.pop('machine', None)
149 if not machine:
150 raise ValueError('implementation must have a machine attribute')
151 setattr(cls, 'machine', machine)
152 field1 = models.CharField(
153 max_length=cls.change_field(),
154 )
155 ModelBase.add_to_class(cls, 'field1', field1)
156
157 cls.imp = Implementation
158
159 def test(self):
160 class Imp3 (self.imp,
161 machine='machine'):
162
163 class Meta:
164 app_label = 'fakeapp'
165
166 def absmethod(self):
167 pass
168
169 self.assertTrue(issubclass(Imp3, models.Model))
170 self.assertTrue(issubclass(Imp3, self.imp))
171 self.assertEqual(Imp3.machine, 'machine')
172 field1 = Imp3._meta.get_field('field1')
173 field2 = Imp3._meta.get_field('field2')
174 self.assertEqual(field1.max_length, 10)
175 self.assertEqual(field2.default, 5)
176
177 @classmethod
178 def tearDownClass(cls):
179 cls.patcher.stop()
180
181
182if __name__ == '__main__':
183 unittest.main()
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
Back to Top